SQL 2 counts with different filter
This is the same idea as tombom's answer, but with SQL Server syntax:
SELECT
SUM(CASE WHEN CoumntA < 0 THEN 1 ELSE 0 END) AS LessThanZero,
SUM(CASE WHEN CoumntA > 0 THEN 1 ELSE 0 END) AS GreaterThanZero
FROM TableA
Combine two queries to count distinct strings with different filters
Much faster and simpler with conditional aggregates using the aggregate FILTER
clause:
SELECT source
, count(DISTINCT sku) FILTER (WHERE product_gap = 'yes') AS yes_gap
, count(DISTINCT sku) FILTER (WHERE product_gap = 'no') AS no_gap
FROM product_gaps
WHERE ingestion_date <= '2021-05-25'
GROUP BY source;
See:
- Aggregate columns with additional (distinct) filters
Aside 1: DISTINCT
is a key word, not a function. Don't add parentheses for the single column. distinct(sku)
is short notation for DISTINCT ROW(sku)
. It happens to work because Postgres strips the ROW wrapper for a single column, but it's just noise.
Aside 2: product_gap
should probably be boolean
.
How to count products to multiple filters separated by group
(What is the "question"?)
I think the best way to implement such is to build a query based on the checkboxes, then process the data in a single pass in your application language.
Side issue: Switch from MyISAM to InnoDB.
Side issue: Shrink INT
(which takes 4 bytes) to smaller datatypes.
The point behind these side issues is performance and space. Many of the generated queries will involve a full table scan, filtering as it goes. (That is, INDEXes
will not be useful much of the time.)
The user can click multiple boxes in each grouping, correct? Then consider having, for example, TINYINT UNSIGNED
, which has 8 bits (in 1 byte) to handle up all combinations of up to 8 choices. For example, instead of
AND size_id IN (0, 1) -- 0 means '65in+'; 1 means '50-65in'
do
AND ((size_opts & 0x3) = 0x3)
That is, the bottom bit of size_opts
represents '65in+', etc.
This would shrink the dataset quite a bit and require different pre-processing to generate the queries.
Note that the value of your size_id
is 0..4, my size_opts
would have some or all of the bottom 5 bits on.
ORing together (1 << size_id) values gets you from size_id
to size_opts
.
(More)
There are 2 things going on:
- Filtering (limiting the display by brand/price/color/whatever)
- Counting how many are still in the running (by each remaining criteria)
To goals are needed to make it somewhat efficient:
- Shrink the dataset as much as possible
- Don't include in the table any items that are 'deleted' etc. Don't include any columns that are not relevant to the filtering and counting. They fight with the shrinkage goal
- Shrink the categorization as much as possible. The "bit fiddling" I suggested may be optimal.
- Build the query dynamically. Leave out unnecessary tests. (Example: When nothing is clicked for Brand, don't test for Brand.)
- To rephrase, build a table just for this purpose. Focus on it; ignore all other aspects of the data. Even if the data in this table is redundant, you must optimize this table.
Filter rows by count of two column values
You can just add WHERE status = 'E0'
inside your subquery:
SQL Fiddle (credit to Raging Bull for the fiddle)
SELECT *
FROM (
SELECT *,
COUNT(MembershipNumber) OVER(PARTITION BY EmbossName) AS cnt
FROM card
WHERE status = 'E0'
)A
WHERE cnt > 1
SQL: Multiple count statements with different criteria
SELECT a.code,
COALESCE(b.totalNotXorD, 0 ) totalNotXorD,
COALESCE(c.totalXorD, 0 ) totalXorD,
FROM (SELECT DISTINCT Code FROM tableName) a
LEFT JOIN
(
select code, count(*) totalNotXorD
from table
where status not in('X','D')
group by code
) b ON a.code = b.code
LEFT JOIN
(
select code, count(*) totalXorD
from table
where status in('X','D')
and cancel_date >= '2012-02-01'
group by code
) c ON a.code = c.code
or simply doing CASE
SELECT Code,
SUM(CASE WHEN status NOT IN ('X','D') OR status IS NULL THEN 1 ELSE 0 END) TotalNotXorD,
SUM(CASE WHEN status IN ('X','D') AND cancel_date >= '2012-02-01' THEN 1 ELSE 0 END) TotalXorD
FROM tableName
GROUP BY Code
How to count by filter in SQL query?
SELECT COUNT(t1.id) AS all_records,
SUM(CASE WHEN t1.status = 'completed' THEN 1 ELSE 0 END) AS completed_status_count
FROM t1
Something like this should work. A bit confused about your first count though. Maybe you're looking for something a bit more window-function based. I honestly can't tell.
Multiple counts on different tables in same query
A simple solution would be to use those queries as Sub queries, and combine them:
SELECT
grps.GroupName,
grps.GroupSize,
psts.TotalPosts
FROM (
select count(pg.personID) as GroupSize, g.GroupName, g.GroupID
from Group g inner join PersonGroup pg g.GroupID = pg.GroupID
where LastViewed between @startDate and @enddate and
g.Type = 0
group by g.GroupID, g.GroupName
order by GroupSize) grps
JOIN (
select count(gp.PostID) as TotalPosts, g.GroupName, g.groupID
from Group g inner join GroupPost gp on g.GroupID = gp.GroupID
inner join Post p on gp.PostID = p.PostID
where g.Type = 0 and
gp.Created between @startDate and @enddate
group by g.GroupID, g.GroupName
order by TotalPosts) psts
ON psts.GroupID = grps.GroupID
Related Topics
Conditional Operator in SQL Where Clause
Format Function Not Working in SQL Server 2008 R2
Which Orm Frameworks Will Build and Execute the SQL Ddl for You
SQL Server Automatic Update Datetimestamp Field
How to Return Only 1 Row If Multiple Duplicate Rows and Still Return Rows That Are Not Duplicates
How to Create a Check Constraint on a Varchar Column in SQL Server Specifying a Minimum Data Length
How to Declare Input-Output Parameters in SQL Server Stored Procedure/Function
Can Vba in Ms Access Using Parameter to Prevent SQL Injection
Typo3: SQL Error: 'Incorrect Integer Value: '' for Column 'Sys_Language_Uid' at Row 1'
Expression Engine SQL Query Entries List by Authors
Time Difference in Hours and Seconds Over a Partition Window in Teradata (Sessionizing Records)
Using Table Just After Creating It: Object Does Not Exist
Order Guarantee for Identity Assignment in Multi-Row Insert in SQL Server