I have this table
CustomerID CustomerName Bank Amount
1 Martin BDO Php 55.00
1 Martin CBA Php 150.00
2 Grace BDO Php 45.00
2 Grace BDO Php 4100.00
3 Blake BPI Php 120
I need a sql statement that will display customer with accounts on two different banks.
The result should be
CustomerID CustomerName Bank Amount
1 Martin BDO Php 55.00
1 Martin CBA Php 150.00
How can I get this result?
You can use GROUP BY with HAVING to do this, e.g.:
SELECT *
FROM customer
WHERE customerID IN (
SELECT customerID
FROM customer
GROUP BY customerID
HAVING COUNT(DISTINCT(Bank)) > 1
);
There are several different ways you can get the result that you want. You could join on a subquery that gets a list of CustomerIds with more than one distinct Bank:
select
m1.CustomerId,
m1.CustomerName,
m1.Bank,
m1.Amount
from mytable m1
inner join
(
select
CustomerId
from mytable
group by CustomerId
having count(distinct Bank) >= 2
) m2
on m1.CustomerId = m2.CustomerId;
Or you could use a WHERE EXISTS to also get the result:
select
m.CustomerId,
m.CustomerName,
m.Bank,
m.Amount
from mytable m
where exists (select 1
from mytable m2
where m.CustomerId = m2.CustomerId
and m.Bank <> m2.Bank);
Here is a demo
Related
My table is:
id
student_id
exam_date
license
result
1
101
01-11-2020
B2
FAILED
2
102
15-11-2020
A
PASSED
3
103
22-11-2020
D
FAILED
4
101
01-10-2020
D
PASSED
5
104
01-12-2020
A
PASSED
6
103
29-11-2020
D
PASSED
7
101
01-12-2020
B2
PASSED
8
105
01-09-2020
B2
FAILED
9
104
01-11-2020
A
FAILED
10
105
01-11-2020
B2
PASSED
I need to select the results that would have the first result according to the exam date according to each student id and the license column. If the same student takes different license exam, these two results need to come up as well. But I need only one result row for each student id and license value.
The result should look like this:
id
student_id
exam_date
license
result
1
101
01-11-2020
B2
FAILED
2
102
15-11-2020
A
PASSED
3
103
22-11-2020
D
FAILED
4
101
01-10-2020
D
PASSED
8
105
01-09-2020
B2
FAILED
9
104
01-11-2020
A
FAILED
I've done the research and queries and so far I only got 1 row for student_id although the student takes two different license examination.
The following is my query:
SELECT scct_outer.id, scct_outer.stud_id, scct_outer.exam_date, scct_outer.license, scct_outer.result
FROM stud_cdl_comp_test AS scct_outer
INNER JOIN
(SELECT stud_id, MIN(exam_date) AS MinExamDate
FROM stud_cdl_comp_test AS scct
INNER JOIN stud AS s ON scct.stud_id = s.id
INNER JOIN agent_profile AS ap ON s.agent_profile_id = ap.id
GROUP BY stud_id) groupedscct
ON scct_outer.stud_id = groupedscct.stud_id
AND scct_outer.exam_date = groupedscct.MinExamDate
The problem with you original code is that it is missing a correlartion on the licences between the outer query and the subquery. You would phrase it as:
select s.*
from stud_cdl_comp_test s
inner join (
select student_id, licence, min(exam_date) as minexamdate
from stud_cdl_comp_test as scct
group by stud_id, licence
) s1 on s1.student_id = s.student_id and s1.license = s.license and s1.minexamdate = s.date
I have no idea what stud and agent_profile are, so I removed the from the query.
That said, this is not the method I would recommend - a simple and efficient option is to filter with a subquery:
select *
from stud_cdl_comp_test s
where s.exam_date = (
select min(s1.exam_date)
from stud_cdl_comp_test s1
where s1.student_id = s.student_id and s1.license = s.license
)
This can take advantage of an index on (student_id, license, exam_date).
Alternatively, you can use row_number(), available in MySL 8.0:
select *
from (
select s.*,
row_number() over(partition by student_id, licence order by exam_date) rn
from stud_cdl_comp_test s
) s
where rn = 1
Thinking that you are grouping by student_id in this case is almost incorrect in this case. What are actually grouping by is student + license. Let's call this key combination individual_license.
Here's what the solution will look like:
SELECT
st.id,
st.stud_id,
st.exam_date,
st.license,
st.result
FROM stud_cdl_comp_test AS st
INNER JOIN
(SELECT
MIN(exam_date) AS min_date,
st_inner.student_id,
st_inner.license
FROM stud_cdl_comp_test AS st_inner
GROUP BY st_inner.student_id, st_inner.license
) grouped_inner
ON grouped_inner.student_id = st.student_id
AND grouped_inner.license = st.license
AND grouped_inner.min_date = st.exam_date;
This should work.
I have database where is unique customer ID.
I what to know what products they have bought before specified product. I have a list when specified ID has bought bananas I want to search all products and dates before that.
Example I have data:
CustomerID Product Date
123 banana 2015-03-15
111 banana 2014-07-09
321 banana 2013-04-03
How I can write SQL command search all products what Customer have bought before that date?
Example
CustomerID Product Date
123 Apple 2014-05-07
123 Kiwi 2014-05-06
123 Pen 2012-12-12
111 Pen 2014-07-07
111 Milk 2010-01-30
321 Milk 2012-02-12
This should work for you. The table name is contrived, so you will need to replace it.
SELECT CustomerID, Product, Date
FROM ProductTable p1
WHERE Date < (
SELECT MAX(Date)
FROM ProductTable p2
WHERE p2.CustomerID = p1.CustomerID AND p2.Product = 'banana'
)
ORDER BY CustomerID, Date;
#Peter Abolins's answer is correct, but does not handle the case when the customer has never bought a banana yet.
To handle this case, the request would become:
SELECT CustomerID, Product, Date
FROM ProductTable p1
WHERE Date < (
SELECT IFNULL (
(SELECT MAX(Date)
FROM ProductTable p2
WHERE p2.CustomerID = p1.CustomerID AND p2.Product = 'banana'),
'9999-12-31'
)
)
ORDER BY CustomerID, Date;
PS: I know that this should be a comment, but I cannot comment with this account yet.
I'm not sure if this is what you want but give it a try and look at the results:
SELECT * FROM tableA AS a
JOIN tableA AS b
ON a.CustomerID = b.CustomerID AND a.Date > b.Date
ORDER BY a.CustomerID, a.Product, a.Date
You have two tables, the first table with a list of customer ID, and dates for a specified product, and the second table with the history of product sold to that customer.
We will call them respectively LIST and HIST, you can get your desired output with:
SELECT p1.CustomerID, p2.Product, p2.Date
FROM LIST p1
left join HIST p2 on p2.CustomerID = p1.CustomerID AND P1.Date > P2.Date
ORDER BY p1.CustomerID, p2.Date;
I am looking for a way to list all rows with a duplicate column value.
Example:
Table Address
House Person
23 Joe
23 Jane
27 Chris
29 Grandpa
Expected output:
House Person
23 Joe
23 Jane
I would like to do this so I can manipulate values of people who live in the same house.
I would start by getting all house ids that have more than one person:
SELECT house
FROM myTable
GROUP BY house
HAVING COUNT(*) > 1;
Then, you can join that with your original table to get the people who live in those houses:
SELECT m.*
FROM myTable m
JOIN (SELECT house FROM myTable GROUP BY house HAVING COUNT(*) > 1) temp
ON temp.house = m.house;
Here is an SQL Fiddle example.
Try this :
select b.house, a.person from
(
select person,house
from address
)a,
(
select house,count(house) as cnt
from address
group by house
)b
where a.house = b.house
and b.cnt > 1
this is a huge problem i've to solve in sql but i don't know how.
This is my dataset:
customer; publisher; qty
This is a data sample:
CustA; PublX; 10
CustA; PublZ; 20
CustA; PublF; 30
CustB; PublX; 8
CustC; PublD; 9
CustD; PublX; 9
CustD; MyPub; 18
CustE; PublZ; 3
CustE; MyPub; 8
I need to do a Query that get ONLY Customer without "MyPubl" as publisher.
Obviously i can't do :
SELECT * from myTable where Publisher <>"MyPubl"
One solution can be that i create a subset table that aggregate customer in one row like this:
CustA; PublX PublZ PublF; 60
CustB; PublX; 8
etc...
Then with a INSTR i check if MyPub exists in second field ...
This solution my work.. so i ask you How can i do this in SQL (aggregate 'same' customers in one row) ?
Any others suggestion (maybe more elegant) ?
Thanks
You can use NOT IN with a sub query:
SELECT
customer,
publisher,
qty
FROM
books
WHERE
customer NOT IN (
SELECT
DISTINCT customer
FROM
books
WHERE
publisher = 'MyPub'
)
SQL Fiddle Demo
Which will output:
CUSTOMER | PUBLISHER | QTY
---------+-----------+-----
CustA | PublZ | 20
CustA | PublF | 30
CustB | PublX | 8
CustC | PublD | 9
Maybe this:
SELECT * FROM myTable
WHERE customer NOT IN (SELECT customer FROM myTable WHERE Publisher = "MyPubl")
Or if you just want the customers
SELECT DISTINCT customer FROM myTable
Or old skool...
SELECT DISTINCT x.customer
FROM my_table x
LEFT
JOIN my_table y
ON y.customer = x.customer
AND y.publisher = 'MyPub'
WHERE y.customer IS NULL;
I have 2 tables.
Table Matches
id | TeamA | TeamB
--------------
1 | Barça | Madrid
2 | Valencia | Depotivo
Table Payments
idMatch | User | Quantity
---------------------------
1 | Me | 50
2 | Me | 100
Then in one query I want to get TeamA, TeamB, User and Quantity if they have same id.
I've tried this but it fails.
SELECT TeamA, TeamB FROM Matches WHERE id IN (SELECT idMatch, TeamA, TeamB FROM Payments)
try this
SELECT TeamA, TeamB ,User , Quantity FROM Matches m
inner join Payments p
on p.idMatch = m.id
WHERE id IN
(SELECT idMatch FROM Payments)
DEMO HERE
you can use joins
select Matches.TeamA,Matches.TeamB,Payments.User,Payments.Quantity from Matches,Payments where Matches.id=Payments.idMatch
try this
SELECT payments.user,
payments.quantity
FROM
Payments
INNER JOIN Matches ON (Matches.id = Payments.idMatch);
IN() should contain a list of values like IN('red','green','blue') or IN(1,3,53). SELECT is fine, but it has to return a single field. This would work.
SELECT TeamA, TeamB FROM Matches
WHERE id IN (
SELECT idMatch FROM Payments
)
However it looks like you want to achieve something you need JOIN or GROUP BY for.
Try
SELECT
TeamA,
TeamB,
payments.user,
payments.quantity
FROM
matches
JOIN payments ON ( matches.id = payments.matchid )
select m.TeamA,m.TeamB,p.`User`,p.Quantity from matches m INNER join
payments p where p.idMatch=m.id