Duplicate MySQL rows - mysql

I would like to write a query to pick out rows with the same cottageid, from, and to values, so in this case it would pick out the rows with the id 991, and 992. The table name is datesBooked.

You can join the table with itself:
select d1.id,d2.id from datesBooked d1
inner join datesBooked d2 on
d1.cottageid=d2.cottageid
and d1.from = d2.from
and d1.to = d2.to
and d1.id<d2.id
That would give you the duplicates. I am only getting the ones that have lesser id than the following one (that way you will get the duplicates in the right column, and the originals in the first one)

Try this:
SELECT * FROM datesBooked
GROUP BY cottageid, from, to
HAVING COUNT(cottageid) > 1

Related

The query gives single row query returns more than one row

I'm trying to show staff_code, staff_name and dept_name for those who have taken one book.
Here's my query:
SELECT SM.STAFF_CODE,SM.STAFF_NAME,DM.DEPT_NAME,BT.BOOK_CODE
FROM STAFF_MASTER SM,DEPARTMENT_MASTER DM,BOOK_TRANSACTIONS BT
WHERE SM.DEPT_CODE =DM.DEPT_CODE
AND SM.STAFF_CODE = (
SELECT STAFF_CODE
FROM BOOK_TRANSACTIONS
HAVING COUNT(*) > 1
GROUP BY STAFF_CODE)
It gives the error:
single-row subquery returns more than one row.
How to solve this?
Change = to IN:
WHERE SM.STAFF_CODE IN (SELECT ...)
Because the select returns multiple values, using equals won't work, but IN returns true if any of the values in a list match. The list can be a hard-coded CSV list, or a select with one column like your query is.
That will fix the error, but you also need to remove BOOK_TRANSACTIONS from the table list and remove BOOK_CODE from the select list.
After making these changes, your query would look like this:
SELECT SM.STAFF_CODE,SM.STAFF_NAME,DM.DEPT_NAME
FROM STAFF_MASTER SM,DEPARTMENT_MASTER DM
WHERE SM.DEPT_CODE =DM.DEPT_CODE
AND SM.STAFF_CODE IN (
SELECT STAFF_CODE
FROM BOOK_TRANSACTIONS
HAVING COUNT(*) > 1
GROUP BY STAFF_CODE)
I recommend learning the modern (now over 25 year old) JOIN syntax.

How to Display 1 Column sum in other Column

I have a table that has different columns display different values.
I need to add a new column that displays sum of 1 column in each row of other column.
This is what i need to display.
I have written following query but its only displaying 1 in each row of last column.
select inStation.name TapInStation , outStation.name TapOutStation,
count(trx.passengerCount) PassengerCount, sum(trx.amount) Fare,
(select sum(passengerCount) from transactions iTrx
where iTrx.ID = trx.ID) PassengerPercent
from transactions trx
inner join
station inStation on inStation.ID = trx.fromStation
inner join
station outStation on outStation.ID = trx.toStation
GROUP BY
TapInStation, TapOutStation
If you want the total, then remove the correlation clause. This may do what you want:
select inStation.name as TapInStation , outStation.name as TapOutStation,
count(trx.passengerCount) as PassengerCount,
sum(trx.amount) as Fare,
(select sum(passengerCount) from transactions iTrx) as PassengerPercent
I'm not sure why you would called the "total" something like PassengerPercent, but this should return the overall total.
I also suspect that you might want a sum() for the previous expression.

mysql query works with some particular records only not with all of the data

first image of student_detail table,second is image of payment_detail table when i fire the query like
SELECT `student_detail`.`id`,
`student_detail`.`first_name`,
`student_detail`.`last_name`,
`student_detail`.`course`,
`payment_detail`.`id`,
`student_id`,
`inst_paid_date`,
`next_inst_date`,
`paid_installment`,
`next_installment_amount`
FROM `student_detail`,`payment_detail`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`) from `payment_detail`)
it do not give any result when records are present like second table but if i delete student id 8 and 9 it gives the result other wise not i cant get how it is conflict with other records when perticularly set the where condition with student_id=10. thanks in advanced
The reason is that you limit your inst_paid_date to the maximum value across the entire payment_detail table. Since this maximum value is for student id 9 when it is present, this conflicts with your filter on student id 10.
Try to add the same filter to your subquery like this:
WHERE
...
AND `student_id`='10'
AND `inst_paid_date` in (select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = '10')
A more generic solution would be to turn the subquery into a correlated subquery. This requires an alias on the outer reference to the payment_detail table:
...
FROM `student_detail`,`payment_detail` as `PD`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `PD`.`student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = `PD`.`student_id`)

Inner join A on B if B not empty, else A

Two tables:
prefix ( id, value )
---------------------
1 'hello'
2 'good afternoon'
3 'good night'
suffix ( id, value )
---------------------
1 'world'
3 'world'
I'd like to get
all from table prefix which can be joined on table suffix via id
result should look like:
prefix.id prefix.value
--------------------------
1 'hello'
3 'good night'
well - quite easy so far...
but if table suffix is empty I'd like everything from table prefix
without subselects/ctes or if.... and in one query fulfilling both conditions!
Is there any trick to get this done by some magic having-clause or tricky something else?
Just for testcases: SQL-fiddle
Well, there is a way, but I agree with others that your requirements make no (practical) sense.
Anyway, here you go:
Join the suffix table twice (each time with a left join). One join is on the id column, the other on an always true condition.
Group the results on the prefix columns you want in the output and at least one non-nullable column of the first instance of suffix.
In the HAVING clause, put a condition that the first suffix column is not null or the number of values of a non-nullable column in the second suffix instance is 0. (Obviously, every group will have the same number of rows, i.e. the count will be the same for every prefix row.)
This is the query:
SELECT prefix.id, prefix.value
FROM prefix
LEFT JOIN suffix ON prefix.id = suffix.id
LEFT JOIN suffix AS test ON 1=1
GROUP BY prefix.id, prefix.value, suffix.id
HAVING suffix.id IS NOT NULL OR COUNT(test.id) = 0;
And there's also a demo at SQL Fiddle.
You need an OR and NOT EXISTS:
SELECT
prefix.id, prefix.value
FROM
prefix
WHERE
EXISTS(SELECT 1 from suffix WHERE prefix.id=suffix.id)
OR NOT EXISTS(SELECT 1 FROM suffix)
Demo
I guess the answer is: no, you can't!
Or if you can: No, you shouldn't.

Subquery returns more than 1 row MySQL

Hey so there are these two tables Name and Code and I am trying to make a table with all the Names and match each existing code to the names. Some Names do not have codes so it should display as NULL for those ones. Anyways this is my code:
SELECT company.name,
(SELECT companyclassification.code
FROM insure_prod.companyclassification
WHERE company.OIQ_ID = companyclassification.ussicClassification_StdCompany)
AS USSIC_Code
FROM insure_prod.company
When I try to run this it displays Error Code: 1242 Subquery returns more than 1 row
Thanks in advance
You cannot have a correlated subquery return more than one row. One thing you can do would be to use a LEFT JOIN instead of the correlated subquery:
SELECT c.name,
cc.code AS USSIC_Code
FROM insure_prod.company c
LEFT JOIN insure_prod.companyclassification cc
on c.OIQ_ID = cc.ussicClassification_StdCompany;
This will return a null for the rows that do not exist in the insure_prod.companyclassification table and if you have more than one row that matches you will return multiple rows for each name. If you do not want to return multiple rows for each name, then you will need to alter the query to return one code for each name.
If you want to continue to use your correlated subquery, then you will have to alter the query to limit the result to one row for each name:
SELECT c.name,
(SELECT cc.code
FROM insure_prod.companyclassification cc
WHERE c.OIQ_ID = cc.ussicClassification_StdCompany
ORDER BY cc.ussicClassification_StdCompany
LIMIT 1) AS USSIC_Code
FROM insure_prod.company c
The select companyclassication.code ... query cannot return more than one row. You're trying to return its results into a field context - a field cannot have more than one value in any given row, and you're trying to stuff in 2 or more result records.