SQL - Confusing Query - mysql

I have a 'photos' table:
photoID (INT), setID (INT)....
18900 , 234 , ...
18901 , 234 , ...
18902 , 234 , ...
18903 , 249 , ...
18904 , 249 , ...
18905 , 249 , ...
I also have a 'photoKeyword' table:
photoID (INT), keywordID (INT)
18900 , 12
18900 , 21
18901 , 17
18905 , 26
18905 , 10
As you can see from my examples above, photos 18902, 18903 and 18904 do NOT have any keywords in the photoKeyword table. This is exactly what I am trying to establish.
I am trying to produce a list of photoID's that don't have keywords but one setID at a time. So as you can see, photo 18902 doesn't have keywords and so does 18903 and 18904 but these three photos have two different setID's.
So running this query once, should only return photo 18902. I would then add keywords to this photo so it won't be a problem again. The next time I run the query it should return photo 18903 and 18904, the next set (setID:249) of photos that do not have keywords.
How is this possible? Is it possible just using SQL? I hope you can understand what I looking to achieve, I lost myself just writing about it!!
Any thoughts gratefully received...

try
SELECT X.photoID FROM photos X
INNER JOIN
(SELECT DISTINCT P.setID FROM
photos P
LEFT OUTER JOIN (SELECT K.photoID, COUNT(*) C FROM photoKeyword K GROUP BY K.photoID) KC ON KC.photoID = P.photoID
GROUP BY P.setID
HAVING SUM (KC.C) < 1) Y ON X.setID = Y.SetID

SELECT photoID
, setID
FROM photos
WHERE photoID NOT IN
( SELECT photoID
FROM photoKeyword
)
AND setID =
( SELECT setID
FROM photos
WHERE photoID NOT IN
( SELECT photoID
FROM photoKeyword
)
ORDER BY setID
LIMIT 1
)

This might be what you need which is quite simple... when you think about it... Ensure your keyword table has an index on the photo id
select
p.PhotoID,
p.SetID
from
Photos p
LEFT JOIN photoKeyword pkey
on p.PhotoID = pkey.PhotoID
where
pkey.PhotoID = null
By doing a LEFT join, we know it will always attempt to the second table. Then, if the second table has no matches, we know the ID trying to join on will be null... So, left join and return only those IDs where the answer is NULL in the second table.

Related

How to make query

review table has store_idx, user_idx etc...
I want to create a query sentence that gets information about the store to which the user has bookmarked with the user_id value entered.
The query sentence I made is
select A.store_name
, A.store_img
, count(B.store_idx) as review_cnt
from board.store A
Left
Join board.review B
On A.store_idx is B.store_idx
where store_idx is (select A.store_idx from bookmark where user_id = ?)
However, nothing came out as a result.
Help me..
Please use below Query:
SELECT store_name
, store_img
, SUM(review_cnt) AS review_cnt
FROM
( SELECT DISTINCT A.store_name
, A.store_img
, CASE WHEN B.store_idx IS NULL THEN 0 ELSE 1 END AS review_cnt
FROM bookmark br
JOIN board.store A
ON A.store_idx = br.store_idx
LEFT
JOIN board.review B
ON A.store_idx = B.store_idx
WHERE br.user_id = ?
)T
The WHERE clause is obviously filtering out all rows. We can't do much about that. But your query is also lacking a GROUP BY, the table aliases can be improved, and the join condition is not correct.
So, try this version:
select s.store_name, s.store_img, count(b.store_idx) as review_cnt
from board.store s left join
board.review r
on s.store_idx = r.store_idx
where b.store_idx in (select b.store_idx
from bookmark b
where b.user_id = ?
);

MySQL group by multiple columns issue

The query below collects temporary overview data for every user into memory table. Basicaly, user sees, count of items by keyword.
The problem is, it calculates total count of items by keyword_id.
What I need is, to calculate item_count by both keyword_id and item_type (Item.type).
SELECT
`Item`.`user_id` AS `user_id` ,
`ItemKeyword`.`keywordID` AS `keyword_id` ,
`Keyword`.`title` AS `keyword_title`,
count(`ItemKeyword`.`ItemID`) AS `ico_count`
FROM
(
(
`ItemKeyword`
JOIN `Item` ON(
(
`Item`.`id` = `ItemKeyword`.`ItemID`
)
)
)
JOIN `Keyword` ON(
(
`Keyword`.`id` = `ItemKeyword`.`keywordID`
)
)
)
GROUP BY
`Item`.`user_id` ,
`ItemKeyword`.`keywordID`;
Details
For example, now result looks like below
Basicaly, item_count is total of all item_types. What I need is, to separate the result below
user_id keyword_id keyword_title item_count
1 9645 surveillance 20
Into something like this:
user_id keyword_id keyword_title item_count item_type
1 9645 surveillance 18 1
1 9645 surveillance 2 2
Where, item_count are calculated by both keyword_id and item_type.
I can't figure out how to include item_type also into this query.
Any suggestions?
I do not understand your love of brackets (parenthesis). Why so many? in my opinion you lose the readability. It was just a side note.
If you need an extra grouping level you need to modify the query like this:
SELECT
`Item`.`user_id` AS `user_id` ,
`ItemKeyword`.`keywordID` AS `keyword_id` ,
`Keyword`.`title` AS `keyword_title`,
count(`ItemKeyword`.`ItemID`) AS `ico_count`,
`Item`.`type` AS `item_type`
FROM `ItemKeyword` JOIN `Item` ON
`Item`.`id` = `ItemKeyword`.`ItemID`
JOIN `Keyword` ON
`Keyword`.`id` = `ItemKeyword`.`keywordID`
GROUP BY
`Item`.`user_id` ,
`Item`.`type` ,
`ItemKeyword`.`keywordID`,
`Keyword`.`title`;

Join 2 tables and display by id,priority & number

Example tables and desired result:
The result table shown below is the output I actually want.
tried the following query with pivot:
with pivot_data AS
(
select client_id
,ph_type
,Ph_number
from client_table
inner join phone_table
on client_table.phone_id = phone_table.ph_id
)
select *
from pivot_data
pivot (sum(ph_number)
for ph_type in ('c','w','h')
);
Result I got:
Any help would be appreciated.
Answers in sql server would be great but oracle & mysql is also welcome if they can point me in the right direction. :)
Thanks in advance.
Oracle Query:
SELECT *
FROM (
SELECT client_id, priority, phone_number, phone_type
FROM client_table c
LEFT OUTER JOIN
phone_table p
ON ( c.phone_id = p.phone_id )
)
PIVOT ( MAX( phone_type ) AS phonetype, MAX( phone_number ) AS phonenumber
FOR priority IN ( 1 AS Prio1, 2 AS Prio2, 3 AS Prio3 ) );
Output:
CLIENT_ID PRIO1_PHONETYPE PRIO1_PHONENUMBER PRIO2_PHONETYPE PRIO2_PHONENUMBER PRIO3_PHONETYPE PRIO3_PHONENUMBER
---------- --------------- ----------------- --------------- ----------------- --------------- -----------------
1 C 9999999999 H 5555555555 W 7777777777
You really need to do some reading on set based thinking and how what you are asking for will be very detrimental to your maintenance of the SSIS solution moving forwards.
All you need to do is export the data as is. If you absolutely have to have it all in the one CSV file, just join the two tables together and retain a normalised, scalable dataset that won't break if the number of priorities increases:
select c.client_id
,c.phone_id
,c.priority
,p.phone_type
,p.phone_number
from #Client c
join #Phone p
on c.phone_id = p.phone_id

SQL Join for retrieving record for a single user

I have user related info split into multiple tables . I am trying to write a join to retrieve data for a single user , a lot of the info is optional , so the entry for many columns may be null , which is okay . I have written the following query , it is working except that it returns all users when I want the user with id '69'
SELECT cur_doctor_names.First_Name, cur_doctor_Names.Last_Name, w.Website
FROM cur_doctor_names
LEFT JOIN (
SELECT *
FROM cur_website
WHERE Userid =69
) AS w ON cur_doctor_names.UserId = w.Userid
I want the following result :
First_Name | Last Name | Website
ABC XYZ Null
where ABC is the name for user with id 69 .
You are only filtering the websites because you are using a left join. You should apply your filter to the doctors table
SELECT
cur_doctor_names.First_Name,
cur_doctor_Names.Last_Name,
w.Website
FROM
cur_doctor_names
LEFT JOIN cur_website AS w
ON cur_doctor_names.UserId = w.Userid
WHERE
cur_doctor_names.UserId = 69
Try writing it like this - your where clause was in the wrong place (also your left join does not need to be written like that):
SELECT cur_doctor_names.First_Name, cur_doctor_Names.Last_Name, w.Website
FROM cur_doctor_names
LEFT JOIN cur_website as w
ON cur_doctor_names.UserId = w.Userid
WHERE cur_doctor_names.userId = 69
I think you can just write
SELECT cur_doctor_names.First_Name, cur_doctor_Names.Last_Name, w.Website
FROM cur_doctor_names
LEFT JOIN cur_website w ON cur_doctor_names.UserId = w.Userid
WHERE Userid =69

MySQL: query'ing results [pic]

I almost have the data I want...but need help filtering it. (pic at bottom)
The query below returns all records with a status of Member-id5 but I need to filter that. Ex: If I did a simple query on ect. (exp_channel_titles) for author_id 323 I would get 5 results. Of those 5 results one row has status = 'Member-id5', another one has a status = 'complete' AND title = %Member% (that's the deciding factor, the row with complete and Member in it). If that row exist then its okay to grab the entry_id of row status = Member-id5 to use for looking up the data in ecd (exp_channel_data) with in it. Any idea on how i can do that? picture enclosed
SELECT
ect.entry_id
, ect.author_id
, ect.title
, ect.status
, ecd.field_id_13
, ecd.field_id_14
, ecd.field_id_15
, ecd.field_id_25
, ecd.field_id_27
, ecd.field_id_28
, ecd.field_id_29
, ecd.field_id_30
, ecd.field_id_31
, ecd.field_id_32
, ecd.field_id_33
, ecd.field_id_34
, ecd.field_id_35
, exm.email
FROM exp_channel_titles as ect
LEFT JOIN exp_channel_data as ecd
ON ecd.entry_id = ect.entry_id
LEFT JOIN exp_members as exm
ON exm.member_id = ect.author_id
WHERE ect.status = 'Members-id5'
The picture is just of a simple query done on exp_channel_titles, of 323 as author_id. its to show how there multiple results and what entry_id i'm trying to get in order to finish my query. entry_id 496 is what I want, and that based on 1. there is a row with %Member% and complete in it. And then row 496 has a status of Members-id5.
SELECT ...
FROM exp_channel_titles as ect
JOIN exp_channel_titles as ect2
ON (
ect2.author_id = ect.author_id
AND ect2.title LIKE '%Member%'
AND ect2.status = 'complete'
)
...
WHERE ect.status = 'Members-id5'