currently i have two tables with some data. the first table has the following:
+----------------+-----------+
| name | member_id |
+----------------+-----------+
| Juice Box | 49432 |
| Rainsurge | 49631 |
| spiderpigrider | 50482 |
+----------------+-----------+
The second table has the following:
+------------+-----------+
| recruit_id | bin(refs) |
+------------+-----------+
| 49432 | 1 |
| 49631 | 1 |
| 49432 | 1 |
| 49631 | 1 |
| 49432 | 1 |
| 49631 | 1 |
| 49432 | 1 |
| 49631 | 1 |
| 49432 | 1 |
| 49631 | 1 |
+------------+-----------+
I would like to return the name, total refs and member_id/recruit_id like so (listing only users with at least 1 ref)
+------------+-----------+------------+
| recruit_id | name | total_refs |
+------------+-----------+------------+
| 49631 | Rainsurge | 5 |
| 49432 | Juice Box | 5 |
+------------+-----------+------------+
select r.recruit_id,bin(r.refs),ipb.name from refs as r
inner join syndicate_ipb.core_members as ipb on ipb.member_id=r.recruit_id;
this returned my data but obviously without a total count and repeated names/ids
select r.recruit_id,count(bin(r.refs)),ipb.name from refs as r
inner join syndicate_ipb.core_members as ipb on ipb.member_id=r.recruit_id;
this returned data with the total count of everyone but only one id/name
+------------+--------------------+-----------+
| recruit_id | count(bin(r.refs)) | name |
+------------+--------------------+-----------+
| 49432 | 10 | Juice Box |
+------------+--------------------+-----------+
this returns the data but again without a count
select distinct r.recruit_id,bin(r.refs),ipb.name from refs as r
inner join syndicate_ipb.core_members as ipb on ipb.member_id=r.recruit_id;
+------------+-------------+-----------+
| recruit_id | bin(r.refs) | name |
+------------+-------------+-----------+
| 49432 | 1 | Juice Box |
| 49631 | 1 | Rainsurge |
+------------+-------------+-----------+
Any help or guidance is greatly appreciated. I feel like i'm close here but just not competent enough with SQL to get it. thanks!
You were almost there. You just missed the GROUP BY clause at the end.
Query:
SELECT
r.recruit_id,
count(bin(r.refs)),
ipb.name
FROM refs AS r
INNER JOIN syndicate_ipb.core_members AS ipb
ON ipb.member_id = r.recruit_id
GROUP BY r.recruit_id;
Note:
If bin(refs) column always contains value 1 then actually you don't need to keep that column. In that case you can use count(*) or count(r.recruit_id) to get the count.
And if bin(refs) column contains any value then count will not give you the right answer. In that case you need to use sum like Sum( bin(refs)).
You have to use the group by clause:
select r.recruit_id, ipb.name, count(bin(refs)) as total_refs
from refs as r
inner join syndicate_ipb.core_members as ipb
on ipb.member_id=r.recruit_id
group by r.recruit_id, ipb.name
having count(bin(refs)) >= 1
This group by r.recruit_id, ipb.name will group the results and this having count(bin(refs)) >= 1 will garante that it only returns members with at least one ref
Do not only group your columns just by the ones you want. Even though MySql allows it, it is not SQL Ansi pattern and even MySql now is complying with it. Use an aggregation function grouping with your entire columns on the select statement.
SELECT ipb.*, COUNT(`r`.`recruit_id`) AS cid FROM `ipb`
INNER JOIN `r` ON `r`.`join_id` = ipb.`member_id`
GROUP BY ipb.`member_id`
Related
I have an SQL model (MySQL v8.0.20) that describes a physical card with 1 or 2 faces. Because card faces can appear on multiple physical cards, I've modeled this as a many-many relationship using the join table cardFaces.
I'm now trying to get a list of distinct front facing cards. That is if a card has only 1 face, it would be represented once, if it has 2 faces, it would be represented twice (once for each side front facing).
Input
The join table currently looks like this (simplified for question):
SELECT * FROM cardFaces;
+----+--------+--------+
| id | cardId | faceId |
+----+--------+--------+
| 1 | A | 1 |
| 2 | B | 2 |
| 3 | B | 3 |
+----+--------+--------+
Expected Output
The result I'm expecting to achieve is this:
+--------+-------------+------------+
| cardId | frontFaceId | backFaceId |
+--------+-------------+------------+
| A | 1 | NULL |
| B | 2 | 3 |
| B | 3 | 2 |
+--------+-------------+------------+
Current Output
I've only gotten so far as self-joining and removing duplicates, but I can't figure out how to introduce NULL as the backFaceId for cards with only 1 face.
SELECT frontFace.cardId, frontFace.faceId frontFaceId, backFace.faceId backFaceId
FROM cardFaces frontFace
LEFT JOIN cardFaces backFace
ON frontFace.cardId = backFace.cardId
WHERE backFace.id != frontFace.id;
+--------+-------------+------------+
| cardId | frontFaceId | backFaceId |
+--------+-------------+------------+
| B | 2 | 3 |
| B | 3 | 2 |
+--------+-------------+------------+
Move the where condition to the on clause:
SELECT frontFace.cardId, frontFace.faceId frontFaceId, backFace.faceId backFaceId
FROM cardFaces frontFace LEFT JOIN
cardFaces backFace
ON frontFace.cardId = backFace.cardId AND
backFace.id <> frontFace.id;
NULLs fail almost all comparisons, including <>, turning the outer join into an inner join.
I have 2 tables:
clients_db
| clnt_id | clnt_sid | usr_sid | clnt_name |
| 1 | 12345678 | 10001 | Peter |
| 2 | 87654321 | 10001 | Mikey |
aircon_client_db
| ac_id | clnt_sid |
| 1 | 12345678 |
| 2 | 12345678 |
| 3 | 12345678 |
| 4 | 87654321 |
| 5 | 87654321 |
This is query:
select *,count(air.ac_id) as nAC
from clients_db clnt
left join aircon_client_db air on air.clnt_sid=clnt.clnt_sid
where clnt.usr_sid=?
group by clnt.clnt_sid
order by clnt.clnt_name asc
From the code above. I expect the result clnt_id[1]=3 and clnt_id[2]=2. But the result returns 0 for all. Where should I fix?
You just need to select the count(air.ac_id).
Also replace clnt.usr_sid=? with clnt.clnt_id=? if you're going to expect a result like clnt_id[1]=3.
select count(air.ac_id) as nAC
from clients_db clnt
left join aircon_client_db air on air.clnt_sid=clnt.clnt_sid
where clnt.clnt_id=?
group by clnt.clnt_sid
order by clnt.clnt_name asc
Are you missing clnt_name as column in your question?
Don't use * but explicit column name or in this case you could also use clnt.* (you don't need the value for the left joined table but only the count(*)
select clnt.clnt_id, clnt.clnt_sid ,count(air.ac_id) as nAC
from clients_db clnt
left join aircon_client_db air on trim(air.clnt_sid)=trim(clnt.clnt_sid)
AND trim(clnt.user_sid)= '10001'
group by clnt.clnt_sid
order by clnt.clnt_name asc
My purchaseproduct table
+------------+------------+
| productids | quantities |
+------------+------------+
| 1,3,4,5 | 1,1,1,1 |
| 2,3,4,5 | 1,1,1,1 |
+------------+------------+
My product table
productsid | productsname |
+------------+-----------------------------+
| 1 | Phone |
| 2 | Laptop |
| 3 | Charger |
| 4 | Earphone |
| 5 | Camera |
I want to get product name based on productids in purchaseproduct table
Like below Out put is needed
Phone,Charger,Earphone,Camera (In row one)
Laptop,Charger,Earphone,Camera (In row two)
I tried this below statement and many other
select group_concat(p.productsname) from purchaseproducts as pp join products as p on find_in_set(p.productsid,pp.productids);
But the output I get is
Phone,Charger,Earphone,Camera,Laptop,Charger,Earphone,Camera (All in one row)
How can I achieve the output I need?
You can simply use DISTINCT inside the GROUP_CONCAT :
select pp.productsid , group_concat(DISTINCT p.productsname)
from purchaseproducts pp
join products p
on find_in_set(p.productsid,pp.productids);
GROUP BY pp.productsid
I'm having BookTable in database (with foregin hey LibID):
| BookID | BookName | BookPrice | LibID |
-------------------------------------------
| 1 | Book_1 | 200 | 1 |
| 2 | Book_2 | 100 | 1 |
| 3 | Book_3 | 300 | 2 |
| 4 | Book_4 | 150 | 4 |
and also LibraryTable:
| LibID | LibName | LibLocation |
-----------------------------------
| 1 | Lib_1 | Loc_1 |
| 2 | Lib_2 | Loc_2 |
| 3 | Lib_3 | Loc_3 |
| 4 | Lib_4 | Loc_4 |
I need to write SQL query that will return be the info about the library and number of books for that library:
| LibID | LibName | NumberOfBooks|
------------------------------------
| 1 | Lib_1 | 2 |
| 2 | Lib_2 | 1 |
| 3 | Lib_3 | 0 |
| 4 | Lib_4 | 1 |
It should be one SQL query, probably with nested queries or joins.. Not sure how the query should look like:
SELECT L.LibID AS LibID, L.LibName AS LibName, COUNT(B) AS NumberOfBooks
FROM LibraryTable L, BookTable B
WHERE L.LibID = B.LibID
Will that work?
No, this query will not work. COUNT aggregates data, so you must explicitely tell the DBMS for which group of data you want the count. In your case this is the library (you want one result record per library).
COUNT's parameter is a column, not a table, so change this to * (i.e. count records) or a certain column (e.g. LibID).
The join syntax you are using is valid, but deprecated. Use explicit joins instead. In your case an outer join would even show libraries that have no books at all, if such is possible.
select l.libid, l.libname, count(b.libid) as numberofbooks
from librarytable l
left outer join booktable b on b.libid = l.libid
group by l.libid;
You could also do all this without a join at all and get the book count in a subquery instead. Then you wouldn't have to aggregate. That's way simpler and more readable in my opinion.
select
l.libid,
l.libname,
(select count(*) booktable b where b.libid = l.libid) as numberofbooks
from librarytable l;
SELECT lt.LibID AS LibID, lt.LibName AS LibName, count(*) AS NumberOfBooks
FROM BookTable AS bt
LEFT JOIN LibraryTable AS lt ON bt.LibID = lt.LibID
GROUP BY bt.LibID
I am trying to join two tables and only select the dealers that did not have their promo code used on any order.
How can I do this?
I'm trying this below, but it's not working right. In the example I want to get just Bob, since his promo_code hasn't been used in any orders.
SELECT d.`name`
FROM z_dealer d
LEFT OUTER JOIN z_order o ON (d.promo_code = o.promo_code)
AND o.promo_code IS NULL
Here are my tables...
mysql> select * from z_dealer;
+----+------+------------+
| id | name | promo_code |
+----+------+------------+
| 1 | John | holiday |
| 2 | Suzy | special |
| 3 | Bob | laborday |
+----+------+------------+
mysql> Select * from z_order;
+----+-------+------------+
| id | total | promo_code |
+----+-------+------------+
| 1 | 10 | holiday |
| 2 | 20 | special |
| 3 | 15 | holiday |
| 4 | 45 | special |
+----+-------+------------+
SELECT d.`name` FROM z_dealer d LEFT JOIN z_order o ON (d.promo_code = o.promo_code) WHERE o.promo_code IS NULL
Have you tried INNER JOIN? or You can try IN like this :
SELECT d.name
FROM z_dealer d
WHERE d.promo_code not in( SELECT promo_code FROM z_order)
I'm not entirely sure why it's not working in your example code. I've created the same tables locally and when I run the script you provided I get the single 'Bob' answer.
SELECT d.name
FROM z_dealer d
LEFT OUTER JOIN z_order o ON (d.promo_code = o.promo_code)
AND o.promo_code IS NULL
What results are you seeing exactly?