简体   繁体   中英

SQL query - How to exclude WHERE for specific field

See the SQL query below, it work fine. It calculate the number of Yes, NOT, Other and the number of matching mobile number [Sales field] ( D.MobileNo = S.mobile )

SELECT D.Username, 
      SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes, 
      SUM(CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END) as Not, 
      SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other, 
      SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales, 
      COUNT(*) as TOTAL 
FROM dairy as D 
     LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile 
WHERE source = 'Network' 
      AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 
      AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 
GROUP BY D.Username 
ORDER BY TOTAL DESC

I want to exclude WHERE for the Sales field - it should not be part from CheckDate . Meaning it should check any record in the dairy table without CheckDate for the Sales field.

How can that be done?

If you really want those results in only one query, this might do the trick.

SELECT D.Username, 
    SUM(CASE WHEN D.type = 'Yes' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Yes, 
    SUM(CASE WHEN D.type = 'Not' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Not, 
    SUM(CASE WHEN D.type = ''    AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Other, 
    SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales, 
    COUNT(*) as TOTAL,
    SUM(CASE WHEN UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) AS TOTALINCHECKDATE
FROM dairy as D 
   LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile 
WHERE source = 'Network' 
GROUP BY D.Username 
ORDER BY TOTAL DESC

Note that "TOTAL" will count all rows (including those who where not within your CheckDate range), TOTALINCHECKDATE return the same value as in your previous query.

Obviously, this can still be optimized.

Assuming username exists also in SALES table

SELECT Username,SUM(Yes) As Yes, SUM(`Not`) As `Not`
  , SUM(Other) As Other, SUM(sales) Sales, SUM(total)
FROM (
-- get diary data
SELECT username,mobileNo As mobile, 
      CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END as Yes, 
      CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END as `Not`, 
      CASE WHEN D.type = '' THEN 1 ELSE 0 END as Other, 
      0 As sales, 1 as total
FROM dairy as D 
WHERE source = 'Network' 
      AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 
      AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 

UNION ALL
-- get all sales
SELECT DISTINCT username,mobile, 0 as Yes, 0 as `Not`, 0 As Other, 1 As sales, 0 As total
FROM sales
  WHERE UNIX_TIMESTAMP(CheckDate) >= 1309474800 
      AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 
) AS a
GROUP BY Username

Also try your original query with date addition

SELECT D.Username, 
      SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes, 
      SUM(CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END) as Not, 
      SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other, 
      SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales, 
      COUNT(*) as TOTAL 
FROM dairy as D 
     LEFT JOIN (SELECT DISTINCT mobile FROM sales WHERE UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 ) as S on D.MobileNo = S.mobile 
WHERE source = 'Network' 
      AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 
      AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 
GROUP BY D.Username 
ORDER BY TOTAL DESC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM