I am trying to get all categories with all sub categories using this SQL query:
SELECT
sections.Section_Name,
sections.Section_Page,
topics.Topic_Name,
topics.Topic_Descr,
topics.Section_ID,
(select count(*) from threads WHERE threads.Topic_ID= topics.Topic_ID and threads.Topic_ID=topics.Topic_ID) as Thread,
(select count(*) from threads join posts on posts.Thread_ID= threads.Thread_ID where threads.Topic_ID =topics.Topic_ID) as Post,
**(SELECT Thread_Time
FROM
(SELECT Thread_Time FROM threads
WHERE threads.Topic_ID = Topic_ID
ORDER BY threads.Thread_ID Desc limit 1) AS Time) AS Time**
FROM
topics, sections
WHERE
topics.Section_ID = sections.Section_ID
It works fine but the Thread_Time query shows the same date on all rows (records)?
Using subqueries is fine for this query. If you want the most recent time, then I think you can do:
select s.Section_Name, s.Section_Page,
t.Topic_Name, t.Topic_Descr, t.Section_ID,
(select count(*)
from threads th
where th.Topic_ID = t.Topic_ID
) as Thread,
(select count(*)
from threads th join
posts p
on p.Thread_ID = th.Thread_ID
where th.Topic_ID = t.Topic_ID
) as Post,
(select max(th.Thread_Time)
from threads th
where th.Topic_ID = t.Topic_ID
)as Time
from topics t join
sections s
on t.Section_ID = s.Section_ID;
The problem with your query is this clause: threads.Topic_ID=Topic_ID. This is just referencing the value in the subquery.
Related
I'm trying to grab the first instance of each result with a sysAddress of less than 4. However my statement currently grabs the min(actionTime) result first before applying the where sysAddress < 4. I'm trying to have the input for the inner join as the where sysAddress < 4 however i cant seem to figure out how to do it.
Should i be nesting it all differently? I didnt want to create an additional layer of table joins. Is this possible? I'm a bit lost at all the answers ive found.
SELECT
tblHistoryObject.info,
tblHistory.actionTime,
tblHistoryUser.userID,
tblHistoryUser.firstName,
tblHistoryUser.surname,
tblHistory.eventID,
tblHistoryObject.objectID,
tblHistorySystem.sysAddress
FROM tblHistoryObject
JOIN tblHistory
ON (tblHistory.historyObjectID = tblHistoryObject.historyObjectID)
JOIN tblHistorySystem
ON (tblHistory.historySystemID = tblHistorySystem.historySystemID)
JOIN tblHistoryUser
ON (tblHistory.historyUserID = tblHistoryUser.historyUserID)
INNER JOIN (SELECT
MIN(actionTime) AS recent_date,
historyObjectID
FROM tblHistory
GROUP BY historyObjectID) AS t2
ON t2.historyObjectID = tblHistoryObject.historyObjectID
AND tblHistory.actionTime = t2.recent_date
WHERE sysAddress < 4
ORDER BY actionTime ASC
WITH
all_action_times AS
(
SELECT
tblHistoryObject.info,
tblHistory.actionTime,
tblHistoryUser.userID,
tblHistoryUser.firstName,
tblHistoryUser.surname,
tblHistory.eventID,
tblHistoryObject.objectID,
tblHistorySystem.sysAddress,
ROW_NUMBER() OVER (PARTITION BY tblHistoryObject.historyObjectID
ORDER BY tblHistory.actionTime
)
AS historyObjectID_SeqByActionTime
FROM
tblHistoryObject
INNER JOIN
tblHistory
ON tblHistory.historyObjectID = tblHistoryObject.historyObjectID
INNER JOIN
tblHistorySystem
ON tblHistory.historySystemID = tblHistorySystem.historySystemID
INNER JOIN
tblHistoryUser
ON tblHistory.historyUserID = tblHistoryUser.historyUserID
WHERE
tblHistorySystem.sysAddress < 4
)
SELECT
*
FROM
all_action_times
WHERE
historyObjectID_SeqByActionTime = 1
ORDER BY
actionTime ASC
This does exactly what your original query did, without trying to filter by action_time.
Then it appends a new column, using ROW_NUMBER() to generate sequences from 1 for each individual tblHistoryObject.historyObjectID. Then it takes only the rows where this sequence value is 1 (the first row per historyObjectID, when sorted in action_time order).
This is the SQL statement:
select
ua.*, uuu.user_name
from
(select
ud.dev_id,
(select uud.user_id as user_id
from user_device uud
where ud.dev_id = uud.dev_id and assigned = 1) user_id,
(select count(1)
from user_device du
where du.dev_id = ud.dev_id) user_number,
de.license
from
user_device ud
inner join
device de on ud.dev_id = de.dev_id
where ud.user_id = 'XXXXXX') ua
left join
user_info uuu on uuu.user_id = ua.user_id
Execute the same SQL, it sometimes reports this error, but sometimes it runs just fine.
The error :
and this is what I want (with another user_id yesterday)
The error is pretty self-explanatory. I'm pretty sure it is referring to this subquery:
(select uud.user_id
from user_device uud
where ud.dev_id = uud.dev_id and assigned = 1
)
Clearly, this subquery is returning multiple rows under some circumstances. A quick and dirty fix is to add and rownum = 1 to the where clause.
You can determine where the duplicates are by running:
select uud.dev_id, count(*) as cnt
from user_device uud
where uud.assigned = 1
group by uud.dev_id
having count(*) > 1;
The following works:
SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY, BM.BOQ_ITEM_NO,
IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
AND BCI.STATUS = 'Y'
AND BM.STATUS = 'Y'
order by boq_item_no;
Results:
But after joining many tables with that query, the result is confusing:
SELECT (SELECT CMN_NAME
FROM CMN_MST
WHERE CMN_CODE= BRI.CMN_RLTY_MTRL) MTRL,
RRI.RRI_RLTY_RATE AS RATE,
I.BOQ_ITEM_NO,
(TRIM(TO_CHAR(IBAD.IPABD_CUR_QTY,
'9999999999999999999999999999990.999'))) AS IPABD_CUR_QTY,
TRIM(TO_CHAR(BRI.BRI_WT_FACTOR,
'9999999999999999999999999999990.999')) AS WT,
TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR),
'9999999999999999999999990.999')) AS RLTY_QTY,
(TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR*RRI.RRI_RLTY_RATE),
'9999999999999999999999990.99'))) AS TOT_AMT,
I.TRM_CODE AS TRM
FROM
(SELECT * FROM ipa_boq_abstrct_dtl) IBAD
INNER JOIN
(SELECT * FROM BOQ_RLTY_INF) BRI
ON IBAD.BCI_CODE = BRI.BCI_CODE
INNER JOIN
(SELECT * FROM RLTY_RATE_INF) RRI
ON BRI.CMN_RLTY_MTRL = RRI.CMN_RLTY_MTRL
INNER JOIN
( SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY,
BM.BOQ_ITEM_NO, IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE
BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
and BCI.status = 'Y'
and bm.status = 'Y') I
ON BRI.BCI_CODE = I.BCI_CODE
AND I.TRM_CODE = BRI.TRM_CODE
AND BRI.TRM_CODE =4
group by BRI.CMN_RLTY_MTRL, RRI.RRI_RLTY_RATE, I.BOQ_ITEM_NO,
IBAD.IPABD_CUR_QTY, BRI.BRI_WT_FACTOR, I.TRM_CODE, I.bci_code
order by BRI.CMN_RLTY_MTRL
Results:
TRM should be 11 instead of 4 in the first row.
you getting 4 because you use
AND BRI.TRM_CODE =4
if you remove this criter you can get true result
In your first query, both of the rows you've highlighted have BCI_CODE=1866.
In the second query, you are joining that result set with a number of others (which come from the same tables, which seems odd). In particular, you are joining from the subquery to another table using BCI_CODE, and from there to (SELECT * FROM ipa_boq_abstrct_dtl) IBAD. Since both of the rows from the subquery have the same BCI_CODE, they will join to the same rows in the other tables.
The quantity that you are actually displaying in the second query is from (SELECT * FROM ipa_boq_abstrct_dtl) IBAD, not from the other subquery.
Is the problem simply that you mean to select I.IPABD_CUR_QTY instead of IBAD.IPABD_CUR_QTY?
You might find this clearer if you did not reuse the same aliases for tables at multiple points in the query.
I need to combine two SQL Queries and I'm hurting myself trying to think through it. My first query gets the number of visitors per day and the second query gets the number of unique visitors per day.
Query 1 - For getting the number of visits
SELECT Count(server_instances.game_id) AS visit_count,
refined_player_visits.visit_date AS visit_date
FROM work.refined_player_visits
INNER JOIN tapi.server_instances
ON server_instances.server_id = refined_player_visits.server_id
WHERE ( server_instances.game_id = "31" )
GROUP BY visit_date;
Query 2 - For getting the number of unique visits
SELECT Count(visit_counts.unique_visit_date) AS unique_visits
FROM (SELECT Count(refined_player_visits.server_id) AS visit_count,
refined_player_visits.visit_date AS unique_visit_date
FROM refined_player_visits
INNER JOIN server_instances
ON server_instances.server_id =
refined_player_visits.server_id
WHERE ( server_instances.place_id = "31"
AND refined_player_visits.visit_date <= CURRENT_VISIT_DATE )
GROUP BY refined_player_visits.roblox_id) AS visit_counts
WHERE ( visit_counts.visit_date = CURRENT_VISIT_DATE
AND visit_counts.visit_count = 1 )
Because this was originally for a web application, I got the results back from the first query and looped through each one. During each loop I would do the second query (where CURRENT_VISIT_DATE is actually the visit_date from the first query.
I'd like to turn this into one query using a JOIN, perhaps. I'm migrating to another system and I don't have the option of doing a second query in the loop statement, so I want to just combine the two queries. I can't seem to wrap my head around it, though.
Does this return what you want?
SELECT *
FROM
(
SELECT Count(server_instances.game_id) AS visit_count,
refined_player_visits.visit_date AS visit_date
FROM work.refined_player_visits
INNER JOIN tapi.server_instances
ON server_instances.server_id = refined_player_visits.server_id
WHERE ( server_instances.game_id = "31" )
GROUP BY visit_date
) AS FirstQuery,
(
SELECT Count(visit_counts.unique_visit_date) AS unique_visits
FROM (SELECT Count(refined_player_visits.server_id) AS visit_count,
refined_player_visits.visit_date AS unique_visit_date
FROM refined_player_visits
INNER JOIN server_instances
ON server_instances.server_id =
refined_player_visits.server_id
WHERE (server_instances.place_id = "31"
AND refined_player_visits.visit_date <= FirstQuery.visit_date)
GROUP BY refined_player_visits.roblox_id) AS visit_counts
WHERE ( visit_counts.visit_date = FirstQuery.visit_date
AND visit_counts.visit_count = 1 )
) AS SecondQuery
Hi all I have written the following query to combine the results from 3 tables(tblQuestions,tblReplies,tblTechnology and display the required results as follows
SELECT tech.DatePosted,
tech.QuestionID,
tech.TechnologyName,
tblr3.TechID,
tblr3.QuestionTitle,
tblr3.UserName,
tblr3.ReplyCount,
tblr3.viewCount,
tblr3.date,
tblr3.RepliedName
FROM (SELECT tblr1.DatePosted,
tblr1.QuestionID,
tblr2.TechID,
tblr2.QuestionTitle,
tblr2.UserName,
tblr2.ReplyCount,
tblr2.viewCount,
tblr1.date,
tblr1.RepliedName
FROM (SELECT tblq.DatePosted,
tblq.TechID,
tblq.QuestionID,
tblq.RepliedName,
tblq.QuestionTitle,
tblq.UserName,
tblq.ReplyCount,
tblq.viewCount,
tblq.date
FROM (SELECT q.DatePosted,
q.TechID,
q.QuestionID,
q.QuestionTitle,
q.UserName,
q.ReplyCount,
q.viewCount,
r.date,
r.UserName AS RepliedName
FROM tblQuestions AS q, tblReplies AS r
WHERE r.QuestionID = q.QuestionID
AND r.TechID = q.TechID
AND q.TechID = 1) AS tblq,
(SELECT r.QuestionID,
max(r.date) AS PostedDate
FROM tblReplies AS r
GROUP BY QuestionID) AS tblr
WHERE tblq.QuestionID = tblr.QuestionID
AND tblq.date = tblr.PostedDate) AS tblr1
RIGHT OUTER JOIN
(SELECT q.QuestionID,
q.TechID,
q.UserName,
q.viewCount,
q.ReplyCount,
q.QuestionTitle
FROM tblQuestions AS q
WHERE q.TechID = 1) AS tblr2
ON tblr2.QuestionID = tblr1.QuestionID) AS tblr3
LEFT OUTER JOIN
(SELECT q.QuestionID,
q.DatePosted,
t.TechID,
t.TechName AS TechnologyName
FROM tblTechnology AS t, tblQuestions AS q
WHERE q.TechID = t.TechID) AS tech
ON tblr3.TechID = tech.TechID
AND tblr3.QuestionID = tech.QuestionID
AND tech.TechID = 1
Which gives me the following result as expected but getting NULL at some fields where data to be present
In place of NULL i need to pull out some data which is present in tblQuestions, also is it possible to reduce the query.
From OPs Comment:
I am trying to pull out the questiontitle,username,questionid from tblquestions along with replycount and viewcount and the latest replys that are posted for that questions based on QuestionID and Technology ID from tblreplys
Your query is basically this:
SELECT
blah
FROM
(
(SELECT
blah
FROM
Questions
INNER JOIN Replies ON QuestionID AND TechID) tblr1
RIGHT JOIN Questions tblr2 ON QuestionID
) tblr3
LEFT JOIN Technologies ON tblr3.tblr1.QuestionID = Technologies.QuestionID
I know that isn't a valid query but bear with me. tblr1contains an INNER JOIN between questions and answers. However because there are no answers to the salary question these records are NULLfor the salaryquestion. The RIGHT JOIN to Questions then introduces the salary question and that exists in the tblr3 result set because it is a RIGHT JOIN even though tblr1 is null for this question.
The LEFT JOIN then to technologies is based on the QuestionID within tblr3 which is really the QuestionID from tblr1. From looking at the column list for the tblr3 sub query, if you change tblr1.QuestionID to tblr2.QuestionID this will ensure that unanswered questions join on to the Technology table
EDIT: I think the following query will give you your results and is much simpler:
WITH LatestReplies AS
(
SELECT
ReplyID,
QuestionID,
ReplyDate,
UserName,
Reply
FROM
(SELECT
ReplyID,
QuestionID,
ReplyDate,
UserName,
Reply,
ROW_NUMBER() OVER (PARTITION BY QuestionID ORDER BY ReplyDate DESC) ReplyOrder
FROM
tblReplies) A
WHERE
ReplyOrder = 1
)
SELECT
tblQuestions.DatePosted,
tblQuestions.QuestionID,
tblTechnology.TechnologyName,
tblQuestions.TechID,
tblQuestions.QuestionTitle,
tblQuestions.UserName,
tblQuestions.ReplyCount,
tblQuestions.ViewCount,
LatestReplies.ReplyDate,
LatestReplies.UserName RepliedName
FROM
tblQuestions
LEFT JOIN tblTechnology ON tblQuestions.TechID = tblTechnology.TechID
LEFT JOIN LatestReplies ON tblQuestions.QuestionID = LatestReplies.QuestionID
Solved with the following after all
select
FI.QuestionID,
FI.QuestionTitle,
FI.UserName,
FI.DatePosted,
FI.[date],
FI.RepliedName,
FI.viewCount,
FI.ReplyCount,
FI.ReplyMsg,
TT.TechID,
TT.TechName
from
tblTechnology TT,
(select distinct
TQ.TechID,
TQ.QuestionID,
TQ.QuestionTitle,
TQ.UserName,
TQ.DatePosted,
TR.[date],
TR.UserName as RepliedName,
TQ.viewCount,
TQ.ReplyCount,
TR.ReplyMsg
from
tblQuestions TQ
LEFT OUTER JOIN tblReplies TR ON
TR.TechID=TQ.TechID
and TR.QuestionID = TQ.QUESTIONID
and TR.[date] in (select
MAX(TR.[date])
from
tblReplies TR
group by
TR.QuestionID)
) FI
where
FI.TechID=TT.TechID
and TT.TechID=#TechID