Merging a SELECT query and a SELECT COUNT query - php

I have a table (associations) in MySql with unique and duplicate keys:
id | key
1 | a
2 | b
3 | b
4 | c
5 | d
6 | d
And I have a table (products) with products:
id | product | type
1 | product1 | one
2 | product2 | one
3 | product3 | two
4 | product4 | two
5 | product5 | two
6 | product6 | two
Now I only what the products that are unique in associations and type 'two' so I get those ID's by this query:
SELECT assoc.id, count(*)
FROM __associations assoc
GROUP BY assoc.key
HAVING COUNT(*) <= 1
Which returns ID 1 and 4 and
SELECT prod.id, prod.product, prod.type
FROM __products prod
WHERE prod.type = two
which return 3,4,5 and 6
But my attempts to combine these two queries and get ID 4 all fails :(

This Query should give you the correct result:
SELECT prod.id, prod.product, prod.type
FROM __products prod
WHERE prod.type = two and prod.id in (SELECT assoc.id
FROM __associations assoc
GROUP BY assoc.key
HAVING COUNT(*) <= 1)

Try this:
SELECT assoc.id, count(*)
FROM __associations assoc
JOIN __products prod ON assoc.id = prod.id
GROUP BY assoc.key
HAVING COUNT(*) <= 1 AND
COUNT(CASE WHEN prod.type = 'two' THEN 1 END) > 0
The query uses a conditional aggregate in its HAVING clause, in order to filter out assoc.key groups not being related to at least one products record with type = 'two'.

You need to select from multiple tables.
SELECT table1.column1, table2.column2 FROM table1, table2 WHERE table1.column1 = table2.column1;
SQL basics: Query multiple tables
SELECT assoc.id, count(*), prod.product, prod.type
FROM __associations assoc, __products prod´
WHERE prod.id = assoc.id AND prod.type = two
GROUP BY assoc.key
HAVING COUNT(*) <= 1

Related

Select the rows with lowest value in specific column from those who match the other critarias

I have created an SQL table to save events data into it.
Each event can have multiple occurrences and when I filter them on site - I want to have the first matching occurrence of each event. each occurrence is saved in a different row, which contains a column for the general event_id and specific occ_id to each occurrence.
I need to get from the matching rows - only one row from each event_id, and it needs to be the one with the lowest occ_id value.
i.e.
gen_id | event_id | occ_id | month
------------------------------------
1 | 190 | 1 | 4
2 | 190 | 2 | 4
3 | 190 | 3 | 4
4 | 192 | 1 | 4
5 | 192 | 2 | 4
6 | 192 | 3 | 4
7 | 193 | 1 | 5
8 | 193 | 2 | 5
If I'm looking for events from month = 4, I need to get the events (gen_id): 1,4
and if I'm looking for month = 5 I need to get only event (gen_id): 7
My SQL query right now gets the matching events but with no occ_id filteration:
(it looks something like this right now)
SELECT
event_id,
event_title,
occ_id
FROM
table_name
WHERE month = 4
GROUP BY event_id
ORDER BY
event_id
DESC
I have tried to also use MIN / MAX but I guess it either not the right handler for this case or I'm using it wrong...
You want to filter. One method uses a correlated subquery in the WHERE clause:
select t.*
from table_name t
where t.occ_id = (select min(t2.occ_id)
from table_name t2
where t2.event_id = t.event_id
);
However, the lowest value always seems to be "1", so this might work as well:
select t.*
from table_name t
where t.month = 4 and
t.occ_id = 1;
To add month, you can add it to the outer query:
select t.*
from table_name t
where t.month = 4 and
t.occ_id = (select min(t2.occ_id)
from table_name t2
where t2.event_id = t.event_id and
t2.month = t.month
);
umm,
select t.event_id, t.occ_id, t.month, min(t.gen_id) from (
select event_id,month,min(occ_id) as min_occ_id from t where month=5 group by event_id, month
) t1 join t on t1.min_occ_id = t.occ_id and t1.event_id = t.event_id and t1.month = t.month
group by t.event_id, t.occ_id, t.month;
if columns event_id,occ_id,month make up an UNIQUE KEY, the SQL can be simplified.
select t.event_id, t.occ_id, t.month, t.gen_id from (
select event_id,month,min(occ_id) as min_occ_id from t where month=5 group by event_id, month
) t1 join t on t1.min_occ_id = t.occ_id and t1.event_id = t.event_id and t1.month = t.month

Get result from three tables using join from which one table contain multiple result

I have three tables with the following columns and data:
table_one
id | balance
100 | 10.00
101 | 5.00
102 | 8.00
table_two
id | number
100 | 0890980980
100 | 7657657655
101 | 7657657656
102 | 1231231233
table_three
id | name | active
100 | nameOne | 1
101 | nameTwo | 0
102 | namrThree | 1
Now my query will be
Query 1. SELECT * FROM table_one WHERE balance <= 8
Query 2. SELECT number(only first_matched_row) FROM table_two WHERE table_one.id = table_two.id
Query 3. SELECT name FROM table_three WHERE table_three.id = table_one.id AND table_three.active = 1
How can I join these three queries and get a single query.
Please note that table_two will get multiple rows so I want take the first matched row and omit the rest where table_two.id matches.
Expected Result:
id | name | number
100 | nameOne | 0890890890
102 | nameThree | 1231231233
SOLVED ANSWER:
Select onetwo.id, three.name, two.number from
(Select two.id from
(SELECT id as id1 FROM table_one WHERE balance <= 8)one
inner join
table_two two on one.id1 = two.id
)onetwo
inner join
table_two two on two.id=onetwo.id
inner join
table_three three on three.id = onetwo.id AND three.active = 1 group by two.id
Would you try:
Select onetwo.id, three.name, onetwo.number from
(Select two.id from
(SELECT id as id1 FROM table_one WHERE balance <= 8)one
inner join
table_two two on one.id1 = two.id
)onetwo
inner join
table_three three on three.id = onetwo.id AND three.active = 1 group by onetwo.id
You can have more elegant queries using advanced RDBMS, but not with MySQL unfortunately.

How to count the number of grouped rows in mysql when I already count the total rows

I have the below table and I want to do the following:
Count the number of times each item appears in the table
Count the DISTINCT number of items
Group the items by name
+-------+---------+
| id | names |
+-------+---------+
| 1 | Apple |
| 2 | Orange |
| 3 | Grape |
| 4 | Apple |
| 5 | Apple |
| 6 | Orange |
| 7 | Apple |
| 8 | Grape |
+-------+---------+
For the 1. and 3. points I have the following query which works quite well:
SELECT * ,
COUNT(names) as count_name,
FROM tbl_products WHERE type = '1'
GROUP BY names
So I get:
Apple (4)
Orange (2)
Grape (2)
Now I want to also count the number of grouped by rows and added a line to count the distinct elements, however there is some problem, since MySQL accepts the query but cannot output a result:
SELECT * ,
COUNT(names) as count_name,
COUNT(DISTINCT names) as count_total
FROM tbl_products WHERE type = '1'
GROUP BY names
Can anyone advice what might be the problem?
EDIT: For more clearance I want to get a table like this:
+-------+---------+------------+-------------+
| id | names | count_ctg | count_total |
+-------+---------+------------+-------------+
| 1 | Apple | 4 | 3 |
| 2 | Orange | 2 | 3 |
| 3 | Grape | 2 | 3 |
+-------+---------+------------+-------------+
Why not just use the query you are using:
SELECT * ,
COUNT(names) as count_name,
FROM tbl_products WHERE type = '1'
GROUP BY names
This query achieves all three objectives.
1) You get a count of the number of each name value in count_name.
2) The number of distinct names values will be equal to the number of rows in the result set , since you are grouping by names. Pretty much any client-side MySQL DB connection library will enable you to retrieve this value.
3) You meet your third criteria of grouping by name by explictly using GROUP BY names
Of course the value for id in the result set is meaningless, you may want to only select names and count_names.
1-.Count the number of times each item appears in the table:
SELECT names, count(names) FROM tbl_products WHERE type = '1' group by names
2-. How many distinct items exist in the table:
SELECT DISTINCT names FROM tbl_products WHERE type = '1'
3-. Group the items by name:
SELECT count(DISTINCT names) as Total FROM tbl_products WHERE type = '1'
As your last EDIT (ALL IN ONE):
SELECT id, names, count(names), total FROM tbl_products, (select count(distinct names) as total from tbl_products) as total WHERE type = '1' group by names
You can get the count of distinct names in a subquery, then OUTER JOIN that thing back into your main query where you already solved for 1 and 3:
SELECT names ,
COUNT(names) as count_name,
Total
FROM tbl_products
OUTER JOIN (SELECT count(DISTINCT names) as Total FROM tbl_products) t2
WHERE type = '1'
GROUP BY names
You can use the SQL Windowing OVER()
This query returns the row_number() function as the id column in the results, and the over(...) for row_number requires an order by clause. You could order by whatever you want, but it most be ordered by something.
;WITH vwGroups (name, Quantity) AS
(
SELECT name
, COUNT(*)
FROM tbl_products
GROUP BY name
)
SELECT ROW_NUMBER() OVER(ORDER BY Quantity DESC, name) AS id
, name
, Quantity AS count_name
, COUNT(*) OVER () AS count_total
FROM vwGroups

how to select sum, and count from diffrent tables using multiple joins

I need to generate some big data from many tables, regarding filters, at there also i need to get the sum of some columns, and also counts of rows like example
i have 5 records
ID | NAME | DELETED
1 | A | 1
2 | A | 0
3 | A | 1
4 | B | 1
5 | C | 1
I have the query,
SELECT p.name, sum(p.deleted) as del, count(p.id) as numbers from products as p
join other AS b ON p.id=b.id
The output i need is,
The sum of deleted records
NAME | Deletion | Count
A | 2 | 3
B | 1 | 1
C | 1 | 1
Try this ::
SELECT
p.name,
sum(p.deleted) as del,
count(id) as numbers
from products as p
join other AS b ON p.id=b.id
group by p.name
You should not need to join to get your result. This should work:
SELECT name, sum(deleted), count(1)
FROM products
GROUP BY name
SELECT name,
SUM(CASE WHEN deleted = 1 THEN 1 ELSE 0 END) Deletion,
COUNT(*) `COunt`
FROM products
GROUP BY name
OR
SELECT name,
SUM(deleted) Deletion,
COUNT(*) `COunt`
FROM products
GROUP BY name;
SQLFiddle Demo (both queries)

Count occurrences of distinct values in 2 fields

I am trying to find a MySQL query that will find distinct values in a particular field, count the number of occurrences of that value in 2 fields (1_user, 2_user) and then order the results by the count.
example db
+------+-----------+-----------+
| id | 1_user | 2_user |
+------+-----------+-----------+
| 1 | 2 | 1 |
| 2 | 3 | 2 |
| 3 | 8 | 7 |
| 4 | 1 | 8 |
| 5 | 2 | 8 |
| 6 | 3 | 8 |
+------+-----------+-----------+
expected result
user count
----- -----
8 4
2 3
3 2
1 2
The Query
SELECT user, count(*) AS count
FROM
(
SELECT 1_user AS USER FROM test
UNION ALL
SELECT 2_user FROM test
) AS all_users
GROUP BY user
ORDER BY count DESC
Explanation
List all the users in the first column.
SELECT 1_user AS USER FROM test
Combine them with the users from the second column.
UNION ALL
SELECT 2_user FROM test
The trick here is the UNION ALL which preserves duplicate values.
The rest is easy -- select the results you want from the subquery:
SELECT user, count(*) AS count
aggregate by user:
GROUP BY user
and prescribe the order:
ORDER BY count DESC
SELECT u, count(u) AS cnt
FROM (
SELECT 1_user AS u FROM table
UNION ALL
SELECT 2_user AS u FROM table
) subquery
GROUP BY u
ORDER by cnt DESC
Take the 2 queries:
SELECT COUNT(*) FROM table GROUP BY 1_user
SELECT COUNT(*) FROM table GROUP BY 2_user
Now combine them:
SELECT user, SUM(count) FROM
((SELECT 1_user as user FROM table)
UNION ALL
(SELECT 2_user as user FROM table))
GROUP BY user, ORDER BY count DESC;
I think this what you are looking for since your expected result did not include 7
select usr, count(usr) cnt from
(
select user_1 usr from users
union all
select user_2 usr from users
) u
where u.usr in (select user_1 from users)
group by usr
order by count(u.usr) desc

Categories