is it wrong if i expect that SQL understands that it should check every single rows to see if S.PersonID is null?
select OrderQty as 'OrderQty',
case
when (select S.PersonID from Sales.Customer as S) is null then 1
else 2
end as 'CaseResult'
from sales.SalesOrderDetail
error: Subquery returned more than 1 value.
if it is wrong then why it understands that it should check every rows one by one in the example below?
select Name,
case ProductCategoryId
when 1 then 'red'
when 2 then 'black'
else 'white
end as 'categoryname'
from production.productcategory
How can i write the first code so that it works like the second code?
You can't use subqueries inside CASE
Also, you are not doing a join between SalesOrderDetail and Customer
select OrderQty as 'OrderQty',
case
when s.Person is null then 1
else 2
end as 'CaseResult'
from sales.SalesOrderDetail sod
left outer join sales.Customer s on sod.PersonId = s.PersonId
You need a correlated subquery, to get it running correctly
CREATE TABLe Customer(PersonID Int)
INSERT INTO Customer VALUEs (1)
CREATE tABLe SalesOrderDetail ( OrderQty int, CustomerID int)
INSERT INTO SalesOrderDetail VALUES(2,1),(3,2)
Records: 2 Duplicates: 0 Warnings: 0
select OrderQty as 'OrderQty',
case
when (select C.PersonID from Customer as C WHERE C.PersonID = S.CustomerID ) is null then 1
else 2
end as 'CaseResult'
from SalesOrderDetail S
OrderQty
CaseResult
2
2
3
1
fiddle
If you have a query that has multiple rows as resultset you need to add a LIMIT to the subquery
CREATE TABLe Customer(PersonID Int)
INSERT INTO Customer VALUEs (1)
CREATE tABLe SalesOrderDetail ( OrderQty int, CustomerID int)
INSERT INTO SalesOrderDetail VALUES(2,1),(3,2)
Records: 2 Duplicates: 0 Warnings: 0
select OrderQty as 'OrderQty',
case
when (select C.PersonID from Customer as C WHERE C.PersonID = S.CustomerID ORDER BY C.PersonID LIMIT 1) is null then 1
else 2
end as 'CaseResult'
from SalesOrderDetail S
OrderQty
CaseResult
2
2
3
1
fiddle
Related
Tabel_A
---------
id name
1 Kursi
2 Roda
3 Gigi
Tabel_B
---------
id id_tabel_A
1 2
Result
--------
name Status
Kursi 0
Roda 1
Gigi 0
Query of the Result : …………………… ?
use left join and case when
select name, case when b.id_tabel_A is null then 0 else 1 end as status
from tableA a left join tableB b on a.id=b.id_tabel_A
You apply IF syntax
SELECT a.name,
IF(
(
SELECT count(b.id_tabel_A)
from Tabel_B as b
WHERE b.id_tabel_A = a.id -- connect
) > 0
, "YES", "NO") as status
from Tabel_A as a
I recommend using exists:
select a.name,
(exists (select 1
from tableB b
where a.id = b.id_tabel_A
)
) as status
from tableA a;
The reason I prefer exists is that it automatically handles duplicates in tableB. You don't have to worry about the query returning duplicate results.
Before a user starts a private chat (between 2 members, not a group chat) I want to check and see if there is already a chat consisting of only these two members. In case they've deleted the chat on their end, when they go to message that same user again I want it to merge with the old chat instead of starting a duplicate chat for the same two members.
This is my structure
`chats` table
id created_time
1 [TIMESTAMP]
2 [TIMESTAMP]
`chats.parties` table
id chat_id member_id invited_by
1 1 1 0 // creator of chat
2 1 2 1
3 1 3 1
4 2 1 0
5 2 2 1
Group by chat_id but only return results that contain a row with member_id=1 and member_id=2; no more, no less.
In the case of the tables above, only the chat_id=2 row(s) would be returned because chat_id=1 contains a 3rd member.
Is this possible with raw SQL? I'd prefer to not loop through in php as it would take a while with a lot of chats.
Here are two different ways to get the result you are looking for:
-- using conditional aggregation
select chat_id from chat_parties
group by chat_id
having sum(case when member_id = 1 then 1 else 0 end) > 0
and sum(case when member_id = 2 then 1 else 0 end) > 0
and sum(case when member_id not in (1, 2) then 1 else 0 end) = 0
-- using a correlated subquery
select chat_id from chat_parties c1
where member_id in (1,2)
and not exists (
select 1 from chat_parties where chat_id = c1.chat_id and member_id not in (1,2)
)
group by chat_id having count(distinct member_id) = 2
Change the table names to fit your actual setup.
Using conditional COUNT
SQL Fiddle Demo
SELECT c.`id`
FROM chats c
LEFT JOIN chats_parties cp
ON c.`id`= cp.`chat_id`
GROUP BY c.`id`
HAVING COUNT(case when `member_id` = 1 then 1 END) >= 1
AND COUNT(case when `member_id` = 2 then 1 END) >= 1
AND COUNT(DISTINCT `member_id` ) = 2
I have a table like this:
id status user_id
1 decline 8
2 approved 7
3 approved 7
4 decline 8
5 decline 7
I want result like this:
accept_status decline_status user_id
2 1 7
0 2 8
Schema (MySQL v5.7)
CREATE TABLE TEST (
id int,
status varchar(20),
user_id int
);
INSERT INTO TEST
VALUES(1,'decline',8);
INSERT INTO TEST
VALUES(2,'approved',7);
INSERT INTO TEST
VALUES(3,'approved',7);
INSERT INTO TEST
VALUES(4,'decline',8);
INSERT INTO TEST
VALUES(5,'decline',7);
Query #1
Used two subqueries during SELECT operation
SELECT
(SELECT count(status) FROM TEST b WHERE status='approved' AND b.user_id = a.user_id) as accept_status,
(SELECT count(status) FROM TEST c WHERE status='decline' AND c.user_id = a.user_id) as decline_status,
a.user_id
FROM TEST a
GROUP BY user_id;
OR
Query #2
SELECT
sum(case when status = 'approved' then 1 else 0 end) AS accept_status,
sum(case when status = 'decline' then 1 else 0 end) AS decline_status,
user_id
FROM TEST
GROUP BY user_id
Output
accept_status
decline_status
user_id
2
1
7
0
2
8
View on DB Fiddle
Using SubQuery or Sub Select you can try this query:
select distinct user_id,
(select count(*) from testtable
where status='approved' and user_id=a.user_id) as accept_status,
(select count(*) from testtable
where status='decline' and user_id=a.user_id) as denied_status
from testtable a;
I am trying to create an UPDATE query that works off of a query
There is a 1->M relationship between ChargeTransaction and ChargeError
ChargeBody is a TEXT field containing json.
When I run the inner query I get a distinct list of chargetransactionids and account ids (1 2 and 3), but when I put it into an UPDATE statement, it assigns an accountid of 3 to all of the chargetransactions.
UPDATE ChargeTransaction
SET AccountId= a.AccountID
FROM
(
SELECT ChargeTransactionId, AccountID
FROM
(
SELECT
[ChargeTransactionId],
CASE WHEN ChargeBody LIKE '%"ReceivingFacility":"998001"%' THEN 1
WHEN ChargeBody LIKE '%"ReceivingFacility":"998002"%' THEN 2
WHEN ChargeBody LIKE '%"ReceivingFacility":"998003"%' THEN 3
ELSE 1
END AS AccountId,
ChargeBody
FROM [ChargesDashboard].[dbo].[ChargeError]
) b
GROUP BY ChargeTransactionId, AccountId
) a
WHERE ChargeTransactionId=a.ChargeTransactionId ;
This may not be the most elegant but I think it would work. I think the problem is that you wanted a join to your derived table.
with myCte as
(
SELECT ChargeTransactionId, AccountID
FROM
(
SELECT
[ChargeTransactionId],
CASE WHEN ChargeBody LIKE '%"ReceivingFacility":"998001"%' THEN 1
WHEN ChargeBody LIKE '%"ReceivingFacility":"998002"%' THEN 2
WHEN ChargeBody LIKE '%"ReceivingFacility":"998003"%' THEN 3
ELSE 1
END AS AccountId,
ChargeBody
FROM [ChargesDashboard].[dbo].[ChargeError]
) b
GROUP BY ChargeTransactionId, AccountId
)
UPDATE C
set AccountID = myCte.AccountID
from ChargeTransaction C
inner join myCte on C.ChargeTransactionId = myCte.ChargeTransactionId
Turns out the problem was that the ChargeTransaction table doesn't have a ChargeTransactionId field, it has an Id field
UPDATE ChargeTransaction
SET AccountId= a.AccountID
FROM
(
SELECT ChargeTransactionId, AccountID
FROM
(
SELECT
[ChargeTransactionId],
CASE WHEN ChargeBody LIKE '%"ReceivingFacility":"998001"%' THEN 1
WHEN ChargeBody LIKE '%"ReceivingFacility":"998002"%' THEN 2
WHEN ChargeBody LIKE '%"ReceivingFacility":"998003"%' THEN 3
ELSE 1
END AS AccountId,
ChargeBody
FROM [ChargesDashboard].[dbo].[ChargeError]
) b
GROUP BY ChargeTransactionId, AccountId
) a
WHERE ChargeTransaction.Id=a.ChargeTransactionId ;
I have two tables (EAV relationship), Customer (id,name) and CustomerVarchar (id,customer_id,attribute_id,value) with relationships below.
Customer hasMany CustomerVarchar
CustomerVarchar belongsTo Customer
I'd like to select a row in Customer based on two rows with specific values in CustomreVarchar. More specifically, I want to retrieve a row in Customer that has these two associated rows with the below condition (must have both of the associated rows in CustomerVarchar):
row 1 has `attribute_id`= 5 and `value`=`John`
row 2 has `attribute_id`= 7 and `value`=`Doe`
Is this possible?
You can use the following to return the customer_id from the customerVarchar table with all of the attributes and values:
select customer_id
from customerVarchar
group by customer_id
having
sum(case when attribute_id = 5 and value = 'John' then 1 else 0 end) > 0
and sum(case when attribute_id = 7 and value = 'Doe' then 1 else 0 end) > 0;
Then you can JOIN this to your customer table to return the customers with that data:
select c.id, c.name
from customer c
inner join
(
select customer_id
from customerVarchar
group by customer_id
having
sum(case when attribute_id = 5 and value = 'John' then 1 else 0 end) > 0
and sum(case when attribute_id = 7 and value = 'Doe' then 1 else 0 end) > 0
) v
on c.id = v.customer_id;
See SQL Fiddle with Demo