SQL: Selecting same Table Column twice based on different WHERE conditions

Viewed 357

I have already tried various proposed solutions here but none of them have proposed what I need.

I need one result of 2 Queries with each one WHERE condition of 1 Table. No Union result please. Both query results need to be in different Columns packed in one result. Let me show you what I mean:

Query 1:

This is the result from the first query

SELECT 
    tbl_Abteilungen.Bezeichnung AS Abteilung, 
    COUNT(tbl_Abteilungen.abteilungen_id) AS [Offene Abteilungstermine] 
FROM 
    tbl_Lieferschein
INNER JOIN 
    tbl_Positionen ON tbl_Lieferschein.lieferschein_id = tbl_Positionen.id_lieferschein
INNER JOIN 
    tbl_Positionen_Abteilungen ON tbl_Positionen.positionen_id = tbl_Positionen_Abteilungen.id_positionen
INNER JOIN 
    tbl_Abteilungen ON tbl_Positionen_Abteilungen.id_abteilungen = tbl_Abteilungen.abteilungen_id
WHERE 
    tbl_Positionen_Abteilungen.fertiggestellt = 0 
    AND tbl_Lieferschein.fertiggestellt = 0 
    AND tbl_Lieferschein.gelöscht = 0
GROUP BY 
    tbl_Abteilungen.Bezeichnung

Query 2:

This is the result from the second query

SELECT 
    COUNT(tbl_Abteilungen.abteilungen_id) AS [Überfällige Abteilungstermine] 
FROM
    tbl_Lieferschein
INNER JOIN 
    tbl_Positionen ON tbl_Lieferschein.lieferschein_id = tbl_Positionen.id_lieferschein
INNER JOIN 
    tbl_Positionen_Abteilungen ON tbl_Positionen.positionen_id = tbl_Positionen_Abteilungen.id_positionen
INNER JOIN 
    tbl_Abteilungen ON tbl_Positionen_Abteilungen.id_abteilungen = tbl_Abteilungen.abteilungen_id
WHERE 
    tbl_Positionen_Abteilungen.fertiggestellt = 0 
    AND tbl_Lieferschein.fertiggestellt = 0 
    AND tbl_Lieferschein.gelöscht = 0 
    AND tbl_Positionen_Abteilungen.Abteilungstermin < CAST(GETDATE() AS DATE)
GROUP BY 
    tbl_Abteilungen.Bezeichnung

All I need is a result like the following:

Needed result:

Needed result

PS: The best would be, if all null results would be shown as '0'

3 Answers

You've basically got two queries that you then join together on tbl_Abteilungen.Bezeichnung

So like this:

SELECT ISNULL(A.Abteilung, B.Abteilung) AS Abteilung, ISNULL(A.[Offene Abteilungstermine],0) AS [Offene Abteilungstermine], 
    ISNULL(B.[Überfällige Abteilungstermine],0) AS [Überfällige Abteilungstermine]
FROM (SELECT tbl_Abteilungen.Bezeichnung AS Abteilung, 
      COUNT(tbl_Abteilungen.abteilungen_id) AS [Offene Abteilungstermine] 
      FROM tbl_Lieferschein
      INNER JOIN tbl_Positionen ON tbl_Lieferschein.lieferschein_id =           tbl_Positionen.id_lieferschein
      INNER JOIN tbl_Positionen_Abteilungen ON tbl_Positionen.positionen_id = tbl_Positionen_Abteilungen.id_positionen
      INNER JOIN tbl_Abteilungen ON tbl_Positionen_Abteilungen.id_abteilungen = tbl_Abteilungen.abteilungen_id
      WHERE tbl_Positionen_Abteilungen.fertiggestellt = 0 
      AND tbl_Lieferschein.fertiggestellt = 0 
      AND tbl_Lieferschein.gelöscht = 0
      GROUP BY tbl_Abteilungen.Bezeichnung) A
FULL OUTER JOIN
      (SELECT tbl_Abteilungen.Bezeichnung AS Abteilung, COUNT(tbl_Abteilungen.abteilungen_id) AS [Überfällige Abteilungstermine] 
      FROM tbl_Lieferschein
      INNER JOIN tbl_Positionen ON tbl_Lieferschein.lieferschein_id = tbl_Positionen.id_lieferschein
      INNER JOIN tbl_Positionen_Abteilungen ON tbl_Positionen.positionen_id = tbl_Positionen_Abteilungen.id_positionen
      INNER JOIN tbl_Abteilungen ON tbl_Positionen_Abteilungen.id_abteilungen = tbl_Abteilungen.abteilungen_id
      WHERE tbl_Positionen_Abteilungen.fertiggestellt = 0 
      AND tbl_Lieferschein.fertiggestellt = 0 
      AND tbl_Lieferschein.gelöscht = 0 AND tbl_Positionen_Abteilungen.Abteilungstermin < cast(GETDATE() AS DATE)
      GROUP BY tbl_Abteilungen.Bezeichnung) B
ON A.Abteilung = B.Abteilung

i.e. your two queries as sub-queries, with a FULL OUTER JOIN. Note that in the second query I've added tbl_Abteilungen.Bezeichnung AS Abteilung as a SELECT column to make the join possible.

You can do this if you use the CASE statement in your select clause and then count only those that match your date parameter as below.

SELECT Abteilung, 
        SUM([Offene Abteilungstermine]) AS [Offene Abteilungstermine],
        SUM([Überfällige Abteilungstermine]) AS [Überfällige Abteilungstermine]
FROM (
    SELECT tbl_Abteilungen.Bezeichnung AS Abteilung,
        [Offene Abteilungstermine] = 1,
        [Überfällige Abteilungstermine] = 
                CASE WHEN tbl_Positionen_Abteilungen.Abteilungstermin < CAST(GETDATE() AS DATE)
                                THEN 1
                    ELSE 0 END
    FROM tbl_Lieferschein
    INNER JOIN tbl_Positionen ON tbl_Lieferschein.lieferschein_id = tbl_Positionen.id_lieferschein
    INNER JOIN tbl_Positionen_Abteilungen ON tbl_Positionen.positionen_id = tbl_Positionen_Abteilungen.id_positionen
    INNER JOIN tbl_Abteilungen ON tbl_Positionen_Abteilungen.id_abteilungen = tbl_Abteilungen.abteilungen_id
    WHERE tbl_Positionen_Abteilungen.fertiggestellt = 0 
    AND tbl_Lieferschein.fertiggestellt = 0 
    AND tbl_Lieferschein.gelöscht = 0
) counts
GROUP BY Abteilung

If both of the queries have the same Grouped by column use CTE's.

In the below code i have constructed an example.

WITH ds1
 AS (SELECT s.CustomerID, 
            SUM(s.Quantity) AS TotalQuantity
     FROM dbo.Sales s
     WHERE s.Quantity > 700
     GROUP BY s.CustomerID),
 ds2
 AS (SELECT s.CustomerID, 
            COUNT(1) AS NR, 
            SUM(s.Quantity) AS TotalQuantity
     FROM dbo.Sales s
     WHERE s.Quantity < 500
     GROUP BY s.CustomerID)
 SELECT c.FirstName, 
        c.LastName, 
        d.TotalQuantity QuantityFrom1stQuery, 
        d2.TotalQuantity QuantityFrom2ndQuery
 FROM dbo.Customers c
      JOIN ds1 d ON d.CustomerID = c.CustomerID
      JOIN ds2 d2 ON d2.CustomerID = c.CustomerID;
Related