2017-02-15 1 views
0

Ich habe eine konstante Gruppe von Benutzern, die ich herausfiltern und auf jede Abfrage anwenden möchte, um zu sehen, was sie in einer App tun. Ich habe hier herumgestochert und geforscht, um ein besseres Gefühl dafür zu bekommen, aber das ist mir immer noch unklar. Ich bin ein Neuling mit SQL-Anweisungen und JAVA. Jede Hilfe, besonders Erklärung ist sehr willkommen.Select-Anweisungen, Joins und Repurpose-Abfrage in SQL

Ich habe versucht, es mit diesen beiden Artikeln ohne Erfolg herauszufinden: 1 & 2; Diese Beispiele zeigen, wie Sie eine Abfrage erstellen und in einer anderen Abfrage verwenden können, was ich versuche zu tun.

Jemand eine Verpackung erwähnt (siehe Ref. 1), das, was ich zu tun versuchen:

mit wählt

Sicher, wickeln Sie Ihre zwei Set-Operationen in äußeren Abfragen, die festen Spalten Quelle, dh SELECT 'horrible_query_1' AS Source, * and SELECT 'ugly_query_2' AS Source, *.

genannt, umfassen

Auf diese Weise wird Ihre UNION Ihnen alle Spalten aus Ihrer Abfrage plus die Quellenkennung geben.

Meine Frage: Ist es möglich, diese Abfragen in separate Abfragen umzuwandeln, ohne Joins mit der Variablen zu machen? Ich verstehe nicht, wie das funktioniert (ich bin mir nicht sicher, ob ich es auch richtig sage).

Dies ist die Benutzergruppe und Filter ich über alle Anfragen umfunktionieren wollen:

<select id="get_num_x_users" resultClass="java.lang.Integer"> 
select count(distinct user_id) from positions sp 
    join position_definitions sd on sp.position_id = sd.id 
    where sd.position like '%catcher%' 
      or lower(sd.position) like '%pitcher%' 
      or lower(sd.position) like '%dh%'; 
    </select> 

in diese Abfrage Repurpose (unter ein paar andere):

<select id="get_u_counts" resultClass="java.lang.Integer"> 
    SELECT COUNT(DISTINCT u.id) 
    FROM searches s 
    JOIN users u 
    ON s.user_id   = u.id 
    WHERE search_date  > DATE_SUB(curdate(), INTERVAL 3 MONTH) 
    AND LENGTH(search_term) > 0 
    AND search_term NOT LIKE ' LIC: SPEC: %' 
    AND u.type != 'coach'; 
</select> 

Mein Versuch (das nicht arbeiten, wenn ich in mysql Datenbank bin):

with get_x_users as (
     select count(distinct user_id) from positions sp 
     join position_definitions sd on sp.position_id = sd.id 
     where sd.position like '%catcher%' 
      or lower(sd.position) like '%pitcher%' 
      or lower(sd.position) like '%dh%';), 

(SELECT COUNT(get_x_users) 
FROM searches s 
JOIN users u 
ON s.user_id = u.id 
AND get_x_users 
WHERE search_date  > DATE_SUB(curdate(), INTERVAL 3 MONTH) 
AND LENGTH(search_term) > 0 
AND u.type != 'coach'); 
+0

Warum geben Sie eine Zählung zurück "Wählen Sie Anzahl (distinct user_id) von Positionen sp ..." aus? Du kannst nicht mitmachen. Sie sollten eine eindeutige Liste von user_id "select distinct user_id aus Positionen sp ..." zurückgeben und user_id in Ihrer Hauptabfrage der u.id beitreten. – strattonn

+0

@strattonn kannst du mir zeigen, was du meinst? – thesayhey

Antwort

0

in SQL wir Tabellen beitreten können zusammen mit einem gemeinsamen Feld. Wenn Sie z. B. ein Feld user_id in zwei verschiedenen Tabellen haben, können Sie die Datensätze mit diesem gemeinsamen Feld abgleichen. Sie können auch einen Join erstellen, der alle Datensätze in einer Tabelle enthält, und nur diejenigen, die in der zweiten Tabelle übereinstimmen. Das ist der Zweck von LEFT JOIN.

Mit diesem Prinzip machen Sie ein wenig umgekehrte Logik und erstellen eine Abfrage, die Ihnen alle Datensätze aus Ihrer Suchanfrage (ExcludeQuery) liefert und sie den Benutzern beifügt, die Sie ausschließen möchten. Dadurch erhalten Sie eine Liste der Datensätze mit und ohne Übereinstimmung mit den ausgeschlossenen Benutzern. Was Sie dann tun, ist, wo Sie nur die Datensätze einschließen, die nicht mit einem ausgeschlossenen Benutzer übereinstimmen. WHERE ExcludeQuery.user_id IS NULL.

SELECT s.* 
FROM searches s 
JOIN users u 
ON s.user_id = u.id 
WHERE search_date  > DATE_SUB(curdate(), INTERVAL 3 MONTH) 
AND LENGTH(search_term) > 0 AND u.type != 'coach' 
LEFT JOIN 
(select user_id from positions sp 
    join position_definitions sd on sp.position_id = sd.id 
    where sd.position like '%catcher%' 
    or lower(sd.position) like '%pitcher%' 
    or lower(sd.position) like '%dh%') AS ExcludeQuery 
ON ExcludeQuery.user_id=s.user_id 
WHERE ExcludeQuery.user_id IS NULL