MySQL not respecting 'HAVING' where aliases are used? - mysql

I've got the following table structure:
CREATE TABLE reservations (
id int auto_increment primary key,
minDate date,
maxDate date
);
CREATE TABLE stays (
id int auto_increment primary key,
reservation_id int,
theDate date
);
INSERT INTO reservations VALUES (null, CURDATE(), CURDATE());
INSERT INTO stays VALUES (null, 1, CURDATE());
It's for a booking system that records reservations (a general container) and stays (someone for each night).
I try to run the following query to extract all reservations that have a different number of days in the database (e.g. the reservation says there should be 2 nights, but there's only 1 in the database, etc)
SELECT
reservations.id AS 'Reservation ID',
reservations.minDate,
reservations.maxDate,
DATEDIFF(reservations.maxDate, reservations.minDate) + 1 AS 'numNights',
COUNT(DISTINCT stays.id) AS 'numStays'
FROM
reservations
LEFT JOIN stays ON reservations.id = stays.reservation_id
GROUP BY
reservations.id
HAVING
`numNights` != `numStays`
ORDER BY
reservations.minDate
This works perfectly on my Windows version of MySQL (xampp), and production CentOS server, but is broken on a testing machine running version 5.6.19-0ubuntu0.14.04.1. On the broken machine, it's pulling back all rows, even though the numNights and numStays columns match.
If I replace the aliases in the HAVING clause with the expressions used in the SELECT part, then it works fine, but I can't understand why it doesn't like the aliases in the HAVING clause (on this version)?
Btw, it's definitely not a no-quote/quote/double-quote/backtick issue, I've tried all combinations. I might have thought it was a charset encoding issue, but DATEDIFF() and COUNT() should be returning the same type of integers back, right? And that wouldn't explain why expressions work in the HAVING part.
I have an SQL Fiddle set up for experimenting as well... it works fine on that too. So now I'm at a loss

This is a "wrong" SQL-Query, because of wrong GROUP BY. But unfortunately, this allowed mysql sometimes. Please check mySql Configuration ONLY_FULL_GROUP_BY and http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html#sqlmode_only_full_group_by

Both the tables contain only single row of data.Without 'Having' clause its returning only 1 row. sql fiddle. As numNights=numStays=1 , while executing 'Having' its giving nothing.I think it'll help you.

Related

Query optimization to comapre dates in mysql

i was in a mysql competion and faced this problem , i 've written ordinary mysql query with select and compare date but it exceeded time limit ?
anyone has an observation how to write a better one here ?
btw i don't have extra info about database it self and we can't use indexing here ( only read from db)
Here's problem statement ..
Given a table called "bugs" with the following columns
(id, token, title, category, device, reported_at, created_at, updated_at).
Find how many bugs were created at "2019-03-01" or later.
It is worth noting that created_at represents the time at which the bug was persisted to the database.
Your query should produce a table with one column called "count".
"Find how many bugs were"
SELECT COUNT(*)
"created at "2019-03-01" or later."
WHERE created_at >= "2019-03-01"
(That works regardless of datatype DATE, DATETIME, or TIMESTAMP.)
"It is worth noting that created_at represents the time at which the bug was persisted to the database."
That just clarifies that `created_at` is the desired column for the problem.
"Your query should produce a table with one column called "count"."
Interpretation 1: "table" = tabular output, a la
mysql> SELECT COUNT(*) AS 'count' FROM t_county;
+-------+
| count |
+-------+
| 3482 |
+-------+
Interpretation 2: An actual table was desired:
CREATE TABLE foo (
`count` INT NOT NULL
)
SELECT COUNT(*) AS 'count'
FROM bugs
WHERE ... ;
This creates a "table" and immediately populates it.
"but it exceeded time limit"
Interpretation 1 -- the query ran too slowly. -- Well, I can't help you there without seeing your query.
Interpretation 2 -- the test was timed. -- Can't help you there. Practice, practice.

DISTINCT work differntly in MYSQL & POSTGRESQL

I have created a sample table report in SQL and filled sample data in it using the following command.
create table report(id int primary key,vistor_id int, branch_id int,date int);
insert into report values (1,1,3,27),(2,1,2,27),(3,1,1,28),(4,1,4,30),(5,1,1,30);
I need to find the list of recently visited(based on date column) branches with out duplication.
So I used the following query
select distinct branch_id from report order by date desc;
It works on MYSQL but shows the following error on POSTGRESQL. How to fix this? Or How can I obtain the same result in POSTGRESQL?(The error is from sqlfiddle.com).
ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select
list Position: 48
Your query is not valid standard SQL. It works in MySQL only if you have option ONLY_FULL_GROUP_BY disabled.
The problem is that there may be multiple dates per branch_id: which one should be used for ordering?
You can use aggregation and be explicit about what you ask for. Say you want to order by the latest date per branch_id:
select branch_id from report group by branch_id order by max(date) desc

Why mysql select count(distinct user_id) return wrong number?

I have a big table in mysql.It has 13 million rows.
Mysql version is 5.7.10.
Table structure as below:
create table table_name (
user_id varchar(20) not null,
item_id varchar(20) not null
);
1. The first sql is:
select count(distinct user_id) from table;
result:760,000
2. The second sql is:
select count(1) from (select user_id from table group by user_id) a;
result:120,000
user_id is not null for each row.
And, the right number is 120,000.Why the first sql get the wrong number?
Then,I run the first sql in hive and spark-sql, the result is 120,000.
So, is this a mysql's bug or something can be setting to make things right?
Thank you!
Update:I try it on another PC, the result of first sql is 120,000.This time get the right number.Mysql version is 5.6.26.
So, maybe it is a bug of 5.7.10.
There are multiple known bugs in MySQL count distinct when a column is included in two-column unique key.
here and here

SUM of differences between selective rows in table

I have a table with call records. Each call has a 'state' CALLSTART and CALLEND, and each call has a unique 'callid'. Also for each record there is a unique autoincrement 'id'. Each row has a MySQL TIMESTAMP field.
In a previous question I asked for a way to calculate the total of seconds of phone calls. This came to this SQL:
SELECT SUM(TIME_TO_SEC(differences))
FROM
(
SELECT SEC_TO_TIME(TIMESTAMPDIFF(SECOND,MIN(timestamp),MAX(timestamp)))as differences
FROM table
GROUP BY callid
)x
Now I would like to know how to do this, only for callid's that also have a row with the state CONNECTED.
Screenshot of table: http://imgur.com/gmdeSaY
Use a having clause:
SELECT SUM(difference)
FROM (SELECT callid, TIMESTAMPDIFF(SECOND, MIN(timestamp), MAX(timestamp)) as difference
FROM table
GROUP BY callid
HAVING SUM(state = 'Connected') > 0
) c;
If you only want the difference in seconds, I simplified the calculation a bit.
EDIT: (for Mihai)
If you put in:
HAVING state in ('Connected')
Then the value of state comes from an arbitrary row for each callid. Not all the rows, just an arbitrary one. You might or might not get lucky. As a general rule, avoid using the MySQL extension that allows "bare" columns in the select and having clauses, unless you really use the feature intentionally and carefully.

SQL Duplicate entry for key 1

I've recently had to take over the management of a database (within a school) that records certain stats, at the start of each year these stats are supposed to be reset.
I've been given a piece of code to run to reset these stats, however it is throwing out a 'Duplicate entry '10172-0' for key 1 error when I try to run it. (the '10172-0' part also happens on various other numbers/student_id's). The code I've been given is:
Insert into cfc.student_stats (students_id, no_cfcs)
Select student_id, 0
from roombookings.students
where student_id >= 1
and student_id <= 15635
I've checked and there aren't duplicate entries when I check out the various student_id's so I'm at a loss with what to do. Underneath the error message I get a button to 'Browse' which then tells me the following:
Error
SQL query: Documentation
SELECT *
FROM
WHERE CONCAT_WS( "-", students_id, no_cfcs ) = "10172-0"
ORDER BY students_id, no_cfcs
MySQL said: Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE CONCAT_WS("-", students_id, no_cfcs)
= "10172-0"' at line 3
I've had a browse through lots of other similar problems on here but none of them seemed to match up with what I was getting (but I don't really understand SQL). Any help appreciated, cheers!
You are doing this
SELECT *
FROM
WHERE
in above query you missed to add table name.
Edit
SELECT *
FROM
roombookings.students
WHERE
Regarding that second error, I'm not sure why you don't just use:
WHERE students_id = 10172 AND no_cfcs = 0
It seems a bit silly and inefficient to turn them into strings just to compare them.
In addition, it appears you haven't selected an actual table to read from, so something like this would be better:
SELECT *
FROM cfc.student_stats
WHERE students_id = 10172
AND no_cfcs = 0
There's also no point ordering by students_id, no_cfcs when you're only allowing one possibility for each, so I removed that bit.
Regarding your first error, I suspect that may be because of duplicate entries in the roombookings.students table. If you do:
select student_id, count(*)
from roombooking.students
where student_id >= 1 and student_id <= 15635
group by student_id
and the second column has any number greater than one in it, you'll get an error trying to insert duplicates into the cfc.student_stats table.
That's because for each student_id in that roombooking.students table, you'll try to create one in the cfc.student_stats table with a primary key made up of the student ID and the constant 0.
If you don't get any counts greater than one, then it's most likely that there's already a row in the cfc.student_stats table with that student ID.