Invalid SQL Query - sql

I have the next query that in my opinion is a valid one, but I keep getting error telling me that there is a proble on "WHERE em.p4 = ue.p3" - Unknown column 'ue.p3' in 'where clause'.
This is the query:
SELECT DISTINCT ue.p3
FROM
table1 AS ue INNER JOIN table2 AS e
ON ue.p3 = e.p3
WHERE
EXISTS(
SELECT 1 FROM (
SELECT (COUNT(*) >= 1) AS MinMutual
FROM table4 AS smm
WHERE
smm.p1 IN (
SELECT sem.p3 FROM table3 AS sem
INNER JOIN table2 AS em ON sem.p3 = em.p3
WHERE em.p4 = ue.p3 AND
sem.type = 'friends' AND em.p2 = 'normal' ) AND
smm.p5 IN (
15000,15151
)
) AS Mutual WHERE
Mutual.MinMutual = TRUE) LIMIT 11
If I execute the sub-query which is inside the EXISTS function, everything is O.K.
PLEASE HELP!

The reason for the error is that you can only reference one subquery layer down when correlating. Look at where the ue alias is defined, and count the number of FROM clauses until to you reach the next reference.
I re-wrote your query as:
SELECT DISTINCT ue.p3
FROM table1 AS ue
JOIN table2 AS e ON ue.p3 = e.p3
WHERE EXISTS(SELECT 1 AS MinMutual
FROM table4 AS smm
JOIN TABLE3 sem ON sem.p3 = smm.p1
AND sem.type = 'friends'
JOIN TABLE2 em ON em.p3 = sem.p3
AND em.p3 = ue.p3
AND em.p2 = 'normal'
WHERE smm.p5 IN (15000,15151)
GROUP BY ? --needs a group by clause, in order to use HAVING
HAVING COUNT(*) >= 1)
LIMIT 11
EXISTS returns true if satisfied -- it doesn't evaluate based on the subquery returning "true". There's no need for the additional subquery you have (which was causing problems anyway).

AFAIK, this kind of correlated query is not doable in mysql as of now. Join to a derived table as opposed to using the exists.

Related

SQL Intersect not supported in Phoenix , alternative for intersect in phoenix?

I have the following SQL expression:
SELECT SS_ITEM_SK AS POP_ITEM_SK
FROM (SELECT SS_ITEM_SK
FROM (SELECT SS_ITEM_SK,(ITEM_SOLD-ITEM_RETURNED) AS TOT_SOLD_QTY FROM (SELECT SS_ITEM_SK,COUNT(SS_ITEM_SK) AS ITEM_SOLD,COUNT(SR_ITEM_SK) AS ITEM_RETURNED FROM STORE_SALES1 right outer join STORE_RETURNS1 on SS_TICKET_NUMBER = SR_TICKET_NUMBER AND SS_ITEM_SK = SR_ITEM_SK GROUP BY SS_ITEM_SK)))
INTERSECT
SELECT CS_ITEM_SK AS POP_ITEM_SK FROM (SELECT CS_ITEM_SK
FROM (SELECT CS_ITEM_SK,(ITEM_SOLD-ITEM_RETURNED) AS TOT_SOLD_QTY FROM (SELECT CS_ITEM_SK,COUNT(CS_ITEM_SK) AS ITEM_SOLD,COUNT(CR_ITEM_SK) AS ITEM_RETURNED FROM CATALOG_SALES1 right outer join CATALOG_RETURNS1 on CS_ORDER_NUMBER = CR_ORDER_NUMBER and CS_ITEM_SK = CR_ITEM_SK GROUP BY CS_ITEM_SK)))
INTERSECT
SELECT WS_ITEM_SK AS POP_ITEM_SK FROM (SELECT WS_ITEM_SK
FROM (SELECT WS_ITEM_SK,(ITEM_SOLD-ITEM_RETURNED) AS TOT_SOLD_QTY FROM (SELECT WS_ITEM_SK,COUNT(WS_ITEM_SK) AS ITEM_SOLD,COUNT(WR_ITEM_SK) AS ITEM_RETURNED FROM WEB_SALES1 right outer join WEB_RETURNS1 on WS_ORDER_NUMBER = WR_ORDER_NUMBER AND WS_ITEM_SK = WR_ITEM_SK GROUP BY WS_ITEM_SK)))
Apache phoenix is not supporting the keyword INTERSECT. Can somebody please help me to correct above query without using INTERSECT?
I think there are multiple ways you can do this:
Join Method
select * from ((query1 inner join query2 on column_names) inner join query3 on column_names)
Exists Method
(query1 where exists (query2 where exists (query3)) )
In Method
(query1 where column_name in (query2 where column_name in (query3)) )
References: https://blog.jooq.org/2015/10/06/you-probably-dont-use-sql-intersect-or-except-often-enough/
and http://phoenix.apache.org/subqueries.html
Although I would use the exists/in over the join since if these queries return huge data then you might have to optimize your queries using this:
https://phoenix.apache.org/joins.html

Query using CASE, WHEN, THEN in postgresql not working

I have three tables, tbl_doctors_details, tbl_time and tbl_token.
I have to select the details from tbl_time or tbl_token. That is if for particular doctor in hospital have t_type is time then select from tbl_time else select from tbl_token.
For example, for doctor_id is 100 and hospital_id 1, the t_type is time. So for this user, details should select from tbl_time table.
Below is the sample structure and data of three tables:
How can I use CASE condition in query here?
I tried:
SELECT *
FROM
( SELECT * CASE WHEN t_type= 'time' FROM dbname.tbl_doctors_details t1 THEN
dbname.tbl_time t2
ELSE
dbname.tbl_token t2
WHERE t1.hospital_id=t2.hospital_id AND t1.doctor_id=t2.doctor_id);
I know the query is not working, but how can I make the query working?
You need to join both tables using two LEFT JOINs and then COALESCE to find the matching data:
SELECT t1.*,
colaesce(t_time.hospid, t_token.hospid),
colaesce(t_time.start, t_token.start)
FROM dbname.tbl_doctors_details t1
LEFT JOIN dbname.tbl_time t_time
ON t1.doctor_id=t_time.doctor_id
AND t1.t_type= 'time'
LEFT JOIN dbname.tbl_token t_token
ON t1.doctor_id=t_token.doctor_id
AND t1.t_type= 'token';
Use CASE WHEN in your SELECT and LEFT JOIN both tables. In both LEFT JOIN use the condition of t_type to join on the tables. In your SELECT you can now check whether table t1 or t2 was joined and select the preferred column. Here's a sample (the selected column is just a sample to illustrate):
SELECT CASE WHEN t1.id IS NULL THEN t2.id ELSE t1.id END AS joined_id
FROM tbl_doctors_details as tbl_base
LEFT JOIN tbl_time t1 ON t1.t_type = 'time' AND t1.doc_id = tbl_base.doc_id
LEFT JOIN tbl_token t2 ON t2.t_type = 'token' AND t2.doc_id = tbl_base.doc_id
Serious smell of doing homework for someone here.. Meh
SELECT
doctors.*
, CASE
WHEN doctors.type = 'time' THEN time.start
ELSE token.start
END AS start
FROM
doctors
LEFT OUTER JOIN time
ON time.doc_id = doctors.doc_id
AND time.hospital_id = doctors.hospital_id
AND doctors.t_type = 'time'
LEFT OUTER JOIN token
ON token.doc_id = doctors.doc_id
AND token.hospital_id = doctors.hospital_id
AND doctors.t_type = 'token'

How to write this SQL statement correctly?

As written in the title: How to write this SQL statement correctly?
select
sl.switch_ip,
sl.switch_name,
count(m.switch_ip) as macentries,
(select arpentries from (select sl1.switch_ip, sl1.switch_name, count(ar.switch_ip) as arpentries
from my_switchlist sl1
left Join my_arptable ar on ar.switch_ip = sl1.switch_ip
group by sl1.switch_ip,sl1.switch_name
order by sl1.switch_ip))
from my_switchlist sl
left Join my_mactable m on m.switch_ip = sl.switch_ip
group by sl.switch_ip,sl.switch_name
order by sl.switch_ip
The select and the sub-select work fine if they are executed separately.
But as soon as I put them together I get the following error:
Error: A subquery has returned not exactly one row.
SQLState: 21000
ErrorCode: -284
Position: 470
Looks like you want both the 'count' aggregates, which should be possible with something like this:
select
macquery.switch_ip,
macquery.switch_name,
macquery.macentries,
arpquery.arpentries
from
(
select
sl.switch_ip as switch_ip,
sl.switch_name as switch_name,
count(m.switch_ip) as macentries
from my_switchlist sl
left outer join my_mactable m
on m.switch_ip = sl.switch_ip
group by
sl.switch_ip,
sl.switch_name
) macquery
join
(
select
sl1.switch_ip as switch_ip,
sl1.switch_name as switch_name,
count(ar.switch_ip) as arpentries
from my_switchlist sl1
left outer join my_arptable ar
on ar.switch_ip = sl1.switch_ip
group by
sl1.switch_ip,
sl1.switch_name
) arpquery
on (macquery.switch_ip = arpquery.switch_ip
and macquery.switch_name = arpquery.switch_name)
Probably there are more than one "sl1.switch_ip,sl1.switch_name" groups in your "my_switchlist, my_arptable" join.
select arpentries from (select sl1.switch_ip, sl1.switch_name, count(ar.switch_ip) as arpentries
from my_switchlist sl1
left Join my_arptable ar on ar.switch_ip = sl1.switch_ip
group by sl1.switch_ip,sl1.switch_name
order by sl1.switch_ip)
The above query should not return more than one result in order you to use its result in your outer query. So probably there is more than one "sl1.switch_ip,sl1.switch_name" group.

Subquery with multiple joins involved

Still trying to get used to writing queries and I've ran into a problem.
Select count(region)
where (regionTable.A=1) in
(
select jxn.id, count(jxn.id) as counts, regionTable.A
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
group by jxn.id, regionTable.A
)
The inner query gives an ID number in one column, the amount of times they appear in the table, and then a bit attribute if they are in region A. The outer query works but the error I get is incorrect syntax near the keyword IN. Of the inner query, I would like a number of how many of them are in region A
You must specify table name in query before where
Select count(region)
from table
where (regionTable.A=1) in
And you must choose one of them.
where regionTable.A = 1
or
where regionTable.A in (..)
Your query has several syntax errors. Based on your comments, I think there is no need for a subquery and you want this:
select jxn.id, count(jxn.id) as counts, regionTable.A
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
where regionTable.A = 1
group by jxn.id, regionTable.A
which can be further simplified to:
select jxn.id, count(jxn.id) as counts
, 1 as A --- you can even omit this line
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
where regionTable.A = 1
group by jxn.id
You are getting the error because of this line:
where (regionTable.A=1)
You cannot specify a condition in a where in clause, it should only be column name
Something like this may be what you want:
SELECT COUNT(*)
FROM
(
select jxn.id, count(jxn.id) as counts, regionTable.A
from
jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
group by jxn.id, regionTable.A
) sq
WHERE sq.a = 1

Conflict in Case Condition in Sql Server query

select CASE when (select distinct BR.BorrowerID from tblBorrow BR
inner join tblWorker W on W.ContractorID=BR.BorrowerID
inner join tblBorrowWorker TWB on TWB.WorkerID=W.WorkerID
inner join tblBorrowWorkerAssign TBWA on TWB.BorrowWorkerAssignmentID=TBWA.BorrowWorkerAssignmentID where TWB.WorkerID=11276) then 'BR.BorrowerID' else 'NotBorrowed' end as BorrowedStatus
Here actually in 'Then' Condition i want to display the BorrowerID,here the subquery part is working well and returning ID ,but when i add with CASE statment its giving an Error
"An expression of non-boolean type specified in a context where a condition is expected, near 'then'."This query is a part of my stored Procedure.What will be the solution
CASE clause expects a boolean condition. Can you use Exists() to check for true condition? Try using exists() for inner select statement (starting with select distinct BR.BorrowerID from tblBorrow BR...)
If you mean to show the value of BR.BorrowerID from the subquery instead of the 'BR.BorrowerID' string constant, you could try the following (assuming you've ensured that the subquery returns no more than one row):
SELECT
ISNULL(
(
SELECT DISTINCT CAST(BR.BorrowerID AS varchar(15))
FROM tblBorrow BR
INNER JOIN tblWorker W ON W.ContractorID = BR.BorrowerID
INNER JOIN tblBorrowWorker TWB ON TWB.WorkerID = W.WorkerID
INNER JOIN tblBorrowWorkerAssign TBWA ON TWB.BorrowWorkerAssignmentID = TBWA.BorrowWorkerAssignmentID
WHERE TWB.WorkerID=11276
),
'NotBorrowed'
)
On the other hand, if that was a full query (not a part of a bigger one) in your post, the following might also be an option:
SELECT DISTINCT ISNULL(CAST(BR.BorrowerID AS varchar(15)), 'NotBorrowed')
FROM
(SELECT 1) x (x)
LEFT JOIN
tblBorrow BR
INNER JOIN tblWorker W ON W.ContractorID = BR.BorrowerID
INNER JOIN tblBorrowWorker TWB ON TWB.WorkerID = W.WorkerID
INNER JOIN tblBorrowWorkerAssign TBWA ON TWB.BorrowWorkerAssignmentID = TBWA.BorrowWorkerAssignmentID
ON TWB.WorkerID = 11276
The (SELECT 1) x (x) "table" is only there to ensure the resulting set is not empty in case the right side of the left join returns no rows.