this is my table
CREATE TABLE IF NOT EXISTS `calls` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` timestamp NOT NULL,
`type` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
and there are data on it its
now i use this query for get type data with same day
SELECT user.name_first calls.date as days, (SELECT GROUP_CONCAT(type) FROM calls WHERE DAY(date) = DAY(days) ) FROM calls JOIN user ON user.user_id = calls.user_id WHERE calls.id IN (SELECT MAX(id) FROM calls GROUP BY DAY(calls.date))
as we see i do this calls.date as days and try to get type for this data by
(SELECT GROUP_CONCAT(type) FROM calls WHERE DAY(date) = DAY(days) )
its work on mysql result in mysql
but when i try it on sqlite its say
no such column: days (code 1): , while compiling
i read sqlite support alias
Related
I have a SQL command that lists the data in the table using lag to calculate with the previous value, to calculate the increase percentage. On my localhost it worked but on my hosting it keeps giving this error, I use mysql.
CREATE TABLE `results`
(
`id` int(11) NOT NULL,
`price` int(11) NOT NULL,
`Date` date DEFAULT NULL,
`grown` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Here is the command I used
SELECT
*, - 100.0 * ( 1-price/ LAG(price) OVER (ORDER BY results.id)) AS Grown
FROM
results AS r
ORDER BY
r.id;
You have “ OVER (ORDER BY t.Id))” but no table/alias called t
I have a call data records table (CDRs) with about 7 million rows,
Each row holds a call record:
unique identifier, caller number, receiving number, answer_datetime and duration_in_seconds
I am looking for an efficient way of finding calls handled by the same receiving number in parallel times.
Any query I tried took too long
The table structure:
CREATE TABLE `cdrs` (
`global_identifier` varchar(32) DEFAULT NULL,
`caller_num` int(14) DEFAULT NULL,
`receiving_num` int(14) DEFAULT NULL,
`call_answer` datetime DEFAULT NULL,
`call_duration` int(7) DEFAULT NULL,
KEY `caller_num` (`caller_num`),
KEY `receiving_num` (`receiving_num`),
KEY `call_answer` (`call_answer`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
;
The query I have already tried:
SELECT
DATE_FORMAT(call_answer,'%Y%m') AS Ym,
b_num,
COUNT(*) AS cnt,
SUM(call_duration) / 60 AS c_dur
FROM
(
SELECT
ycdr.*
FROM
cdrs ycdr
INNER JOIN cdrs ycdr2 ON
ycdr2.receiving_num = ycdr.receiving_num
AND ycdr2.caller_num != ycdr.caller_num
WHERE
ycdr2.call_answer BETWEEN
ycdr.call_answer AND ycdr.call_answer
AND ycdr.call_answer >= '2015-01-01'
AND ycdr.call_answer < '2015-01-05'
GROUP BY
ycdr.global_identifier
) a
;
The EXPLAIN result:
I am using mysql as database and i have a table like the one below.
CREATE TABLE IF NOT EXISTS `logins` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`userid` varchar(255) NOT NULL,
`date` varchar(255) NOT NULL,
`status` varchar(255) NOT NULL,
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=346 ;
I want to sort mysql results with order by.The problem is when i use this sql it takes only the first recod of date. Which is an older date. I want the newest date. last login date of user.
SELECT * FROM `logins` WHERE `status`='valid' GROUP BY `userid` ORDER BY `date` DESC
Any suggestions?
To do this you use a sub query to get the latest record for each user id and then join that to the logins table to get the rest of the details
SELECT logins.*
FROM logins
INNER JOIN
(
SELECT userid, MAX(`date`) AS max_date
FROM `logins`
WHERE `status` = 'valid'
GROUP BY `userid`
) sub0
ON logins.userid = sub0.userid
AND logins.`date` = sub0.max_date
WHERE `status` = 'valid'
You almost had it. Assuming id and userId doesn't evolve from one login to another, asking the MAX date should give you the expected result.
SELECT id, userId, MAX(`date`) AS lastDate, 'valid'
FROM `logins`
WHERE `status`='valid'
GROUP BY `userid`
ORDER BY `lastDate` DESC
Please note that you would need a JOIN if there were data that change between logins in the table.
I'm having troubles to run this SQL:
I think it's a index problem but I don't know because I dind't make this database and I'm just a simple programmer.
The problem is, that table has 64260 records, so that query gets crazy when executing, I have to stop mysql and run again because the computer get frozen.
Thanks.
EDIT: table Schema
CREATE TABLE IF NOT EXISTS `value_magnitudes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`value` float DEFAULT NULL,
`magnitude_id` int(11) DEFAULT NULL,
`sdi_belongs_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`reading_date` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1118402 ;
Query
select * from value_magnitudes
where id in
(
SELECT min(id)
FROM value_magnitudes
WHERE magnitude_id = 234
and date(reading_date) >= '2013-04-01'
group by date(reading_date)
)
EDIT2
First, add an index on (magnitude_id, reading_date):
ALTER TABLE
ADD INDEX magnitude_id__reading_date__IX -- just a name for the index
(magnitude_id, reading_date) ;
Then try this variation:
SELECT vm.*
FROM value_magnitudes AS vm
JOIN
( SELECT MIN(id) AS id
FROM value_magnitudes
WHERE magnitude_id = 234
AND reading_date >= '2013-04-01' -- changed so index is used
GROUP BY DATE(reading_date)
) AS vi
ON vi.id = vm.id ;
The GROUP BY DATE(reading_date) will still need to apply the function to all the selected (thorugh the index) rows and that cannot be improved, unless you follow #jurgen's advice and split the column into date and time columns.
Since you want to get results for every day you need to extract the date from a datetime column with the function date(). That makes indexes useless.
You can split up the reading_date column into reading_date and reading_time. Then you can run the query without a function and indexes will work.
Additionally you can change the query into a join
select *
from value_magnitudes v
inner join
(
SELECT min(id) as id
FROM value_magnitudes
WHERE magnitude_id = 234
and reading_date >= '2013-04-01'
group by reading_date
) x on x.id = v.id
For starters, I would change your query to:
select * from value_magnitudes where id = (
select min(id) from value_magnitudes
where magnitude_id = 234
and DATE(reading_date) >= '2013-04-01'
)
You don't need to use the IN clause when the subquery is only going to return one record.
Then, I would make sure you have an index on magnitude_id and reading_date (probably a two field index) as that's what you are querying against in the subquery. Without that index, you are scanning the table each time.
Also if possible change magnitude_id and reading_date to non null. Null values and indexes are not great fits.
I have a table
CREATE TABLE logs(
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
ip INT(11) UNSIGNED NOT NULL,
`date` TIMESTAMP,
`time` INT(11) UNSIGNED NOT NULL,
referrer VARCHAR(255) NOT NULL,
uri VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
)
And I need to fetch following data and group then by IP:
IP
referrer that was first for IP (date is min.)
last visited uri for IP
number of unique uris
Is it possible to write such query without subqueries?
My solution WITH subqueries:
SELECT
`logs`.`ip`,
(SELECT
`tmp`.`referrer`
FROM
`logs` AS `tmp`
WHERE
`tmp`.`ip` = `logs`.`ip`
ORDER BY `tmp`.`date`
LIMIT 1) 'referrer',
(SELECT
`tmp`.`uri`
FROM
`logs` AS `tmp`
WHERE
`tmp`.`ip` = `logs`.`ip`
ORDER BY
`tmp`.`date` DESC
LIMIT 1) 'uri',
COUNT(DISTINCT (`logs`.`uri`)) 'urls'
FROM
`logs`
GROUP BY
`logs`.`ip`
select
`logs`.`ip`,
`tmp`.`referrer`
`tmp`.`uri`
count(distinct `logs`.`uri`)) as `urls`
from `logs`
left join `tmp` on `tmp`.`ip`=`logs`.`ip`
group by `logs`.`ip`
However this doesn't allow for the order by tmp.date part. If it's absolutely required, let me know in a comment and I'll update this code to allow that.