Selecting rows having more than one connection to another two tables - mysql

Let's say I have three tables:
table `customers` with columns `id`,`name`
table `contracts` with columns `id`, `customer_id`, `text`
table `phones` with columns `id`, customer_id`, `number`
I'd like to select customers which has more than 1 contracts AND more than one phone numbers. I tried to do the folowing:
SELECT * FROM `customers`
WHERE
(SELECT count(*) FROM `contracts` WHERE `customer_id` = `id`) > 1
AND
(SELECT count(*) FROM `phones` WHERE `customer_id` = `id`) > 1
But it produces error #1054 - Unknown column 'customer_id' in 'where clause'

Please try the following query:
SELECT customers.* FROM customers
INNER JOIN
(
SELECT customer_id, count(*) AS count FROM contracts GROUP BY customer_id
HAVING count > 1
) AS contracts
ON customers.id = contracts.customer_id
INNER JOIN
(
SELECT customer_id, count(*) AS count FROM phones GROUP BY customer_id
HAVING count > 1
) AS phones
ON customers.id = phones.customer_id

try this one
SELECT a.id,a.name , COUNT(b.id) AS no_of_contracts
FROM
customers a JOIN contracts b ON a.id = b.customer_id
GROUP BY a.id HAVING no_of_contracts > 1

Related

Referring to CTE in WHERE condition of UPDATE

I'm trying to run a query like this:
WITH cte AS
(
SELECT id, category, SUM(amount) AS sum_amount FROM t1 GROUP BY id, category
)
UPDATE table SET amount = cte.sum_amount WHERE id = cte.id;
However, I keep getting the error
Unknown column 'cte.id in WHERE clause'
Does anyone know how I can refer to my common table expression in the UPDATE query, or otherwise, rewrite it?
You can try below
WITH cte AS
(
SELECT id, SUM(amount) AS sum_amount FROM t1 GROUP BY category
)
UPDATE T
SET T.sum_amount= CT.sum_amount
FROM table T
JOIN cte CT
ON T.id = CT.id
Alternate way with Temporary table, you can read about CTE and Temporary Table
Temporary table:
SELECT id, category, SUM(amount) AS sum_amount
INTO #temp
FROM t1 GROUP BY id, category
Update query with temp table:
UPDATE OT
SET OT.sum_amount= TT.sum_amount
FROM table OT
JOIN #temp TT
ON OT.id = TT.id
CTE:
WITH cte AS
(
SELECT id, category, SUM(amount) AS sum_amount FROM t1 GROUP BY id,category
)
UPDATE T
SET T.sum_amount= CT.sum_amount
FROM table T
JOIN cte CT
ON T.id = CT.id

Update row with maxdate where id from select and maxdate from select is given

I have a select statement that returns a set of ids and a maxdate. Now, I want to update the performance_date in the invoices table with the given maxdate where the given invoices ids.
Select invoices.id, max(invoicepositions.performance_date) as maxdate
from invoices
inner join invoicepositions on invoices.id = invoicepositions.invoice_id
where invoices.performance_date IS NULL
group by invoices.id
(How) is this possible with MySQL?
You can use your current SELECT query as a Derived Table and Join it to the invoices table using id, and then update.
UPDATE invoices AS i
JOIN
(
Select invoices.id, max(invoicepositions.performance_date) as maxdate
from invoices
inner join invoicepositions on invoices.id = invoicepositions.invoice_id
where invoices.performance_date IS NULL
group by invoices.id
) AS dt
ON dt.id = i.id
SET i.performance_date = dt.maxdate

Deleting duplicate data mysql

We have duplicate id where in if we use
SELECT MAX(id), COUNT(id) AS count
FROM user_status
GROUP BY user_id, user_type
HAVING COUNT(*) > 1
we get the duplicate data
Now when I tried to insert it in delete via
DELETE
FROM user_status
WHERE id IN (SELECT MAX(id), COUNT(id) AS count
FROM user_status
GROUP BY user_id, user_type
HAVING COUNT(*) > 1
)
I got the following error
Operand should contain 1 column
How can I fix this ? TIA
As message is clear that you are selecting two columns in the subquery which is not allowed in IN clause but still mysql shows some error in such from of query so please replace the query with join as below
DELETE us
FROM user_status us
INNER JOIN (SELECT MAX(id) id
FROM user_status
GROUP BY user_id, user_type HAVING COUNT(*) > 1) t ON t.id = us.id
How about
DELETE user_status
FROM user_status LEFT JOIN (
SELECT MAX(user_id) maxId
FROM user_status
GROUP BY user_type
) a ON maxId = user_id
WHERE maxId IS NULL;
In your code where col1 in (select col1, col2) the column count simply doesn't match. If you reference each selected column, it works in principle:
DELETE FROM user_status
WHERE (user_id, user_type) NOT IN (
SELECT MAX(user_id) maxId, user_type
FROM (select * from user_status) a
GROUP BY user_type);

SQL Subquery: Column not found

I have the following SQL query:
SELECT t1.`userID`,`name`, COUNT( * ) AS `count`, (SELECT `val` FROM `user-data` WHERE `userID` = t1.userID AND `keyID` = 2 LIMIT 1) AS `staff`
FROM `activity` t1
LEFT JOIN `users` ON `users`.`id` = t1.`userID`
WHERE
t1.`userID` <> 0
GROUP BY t1.`userID`
ORDER BY `count` DESC LIMIT 10
Which works, it takes about 2 seconds. But I want to find entries where staff <> 1:
SELECT t1.`userID`,`name`, COUNT( * ) AS `count`, (SELECT `val` FROM `user-data` WHERE `userID` = t1.userID AND `keyID` = 2 LIMIT 1) AS `staff`
FROM `activity` t1
LEFT JOIN `users` ON `users`.`id` = t1.`userID`
WHERE
t1.`userID` <> 0
AND `staff` <> 1
GROUP BY t1.`userID`
ORDER BY `count` DESC LIMIT 10
I get the error: Unknown column 'staff' in 'where clause'
I can put the subquery in the WHERE clause, but then the query takes 70 seconds.
But surely I should be able to access the column i've reference in the SELECT statement?
Since the select list is processed after the where clause, you cannot reference any calculated field in the where clause via its alias.
You can move the subquery into a join, provided it returns a single record only even if there is no limit clause:
SELECT t1.`userID`,`name`, COUNT( * ) AS `count`, `user-data`.`val` as staff
FROM `activity` t1
LEFT JOIN `users` ON `users`.`id` = t1.`userID`
LEFT JOIN `user-data` ON `user-data`.`userID`=t1.userID AND `user-data`.`keyID` = 2
WHERE
t1.`userID` <> 0
AND `user-data`.`val` <> 1
GROUP BY t1.`userID`, `user-data`.`val`
ORDER BY `count` DESC
LIMIT 10

Mysql UNION as a subquery with an alias field

I have a UNION query as bellow (I have simplified my working query so it is easier to read) :
SELECT count(*) FROM
(SELECT DISTINCT `tableA`.`Store Name` FROM `tableA` UNION SELECT DISTINCT `tableB`.`Store Name` FROM `tableB`) t
This works fine and results in a single number with column name COUNT(*)
I want to get this value as another column in another query so I do :
SELECT DISTINCT `tableC`.`id as PID,
(SELECT count(*) from (SELECT DISTINCT `tableA`.`Store Name` FROM `tableA` UNION SELECT DISTINCT `tableB`.`Store Name` FROM `tableB`) t) AS noofstores
WHERE
.....;
But it wont work! What am I doing wrong? This is part of a bigger query, and all the other subqueries work fine when I do
,
(SELECT .... ) AS column_name
,
Sorry for poor error description. Update :
This is my full query :
SELECT DISTINCT
`tableC`.`id` as PID,
(SELECT count(*)
from
(SELECT DISTINCT `tableA`.`Store Name` FROM `tableA` WHERE `tableA`.`id` = PID
union
SELECT DISTINCT `tableB`.`Store Name` FROM `tableB` WHERE `tableB`.`id` = PID) t) AS mycolumn_name
FROM
`tableC`
Looks like I had the union right and all, but the problem is the PID I am reffering to in the union :
1054 - Unknown column 'PID' in 'where clause'
So how do I solve this?
The PID column does not exist in the inner subquery, only in the outer query. Either you do an inner join in both of the queries in the union on tableC and do the filtering there, or you need to return the id column in the union queries and join the PID on them to do the filtering.
select tableC.id as PID, count(distinct storename)
from
(select distinct id, storename from tableA
union
select distinct id, storename from tableB) t1
inner join tableC on t1.id=tableC.id
group by tableC.id
You have to join thos two tables to get the result
SELECT DISTINCT c.id as PID from table C inner join
(SELECT count(*) from
(SELECT DISTINCT `tableA`.`Store Name` as st
FROM `tableA` UNION SELECT DISTINCT `tableB`.`Store Name` as st
FROM `tableB`) t on t.some_id=c.id WHERE