Mysql query rand() and order by - mysql

Hi i'm trying to get some random results ordered by the location ASC.
This is my query:
SELECT `location`, `route`
FROM (`foo`)
WHERE `location` != ''
ORDER BY RAND(), `location` ASC
LIMIT 8
the problem is that it gets randomly but doesn't orders then by "location" ASC, also if i do this:
SELECT `location`, `route`
FROM (`foo`)
WHERE `location` != ''
ORDER BY `location` ASC,RAND()
LIMIT 8
it doesn't gets randomly.
How can i get both togheter RAND() and ORDER BY location ASC ?

You need nested statements/queries:
SELECT *
FROM (
SELECT `location`, `route`
FROM `foo`
WHERE `location` != ''
ORDER BY RAND()
LIMIT 8) AS `temp`
ORDER BY `location` ASC;

Related

Set MYSQL WHERE condition from previous SELECT

I have the following MySQL query
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
This will grab me a random category where there is at least 5 questions in that category.
Now I want to grab all the rows for that category. So how can I do a second SELECT WHERE category is equal to the category returned from the previous query?
I tried the following but I believe the RAND() is causing it to crash/timeout.
SELECT *
FROM `jeopardy_questions`
WHERE `category` = (
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
)
You can use the above query as a subquery. Something like this:
SELECT *
FROM `jeopardy_questions`
WHERE `category` = (
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
)

Limit the sum only on the top 10 amount

I have a mysql table with that is called transactions and have the following fields: user (varchar), amount (float).
I want to make a group by like this
select `user`
, sum(`amount`) as s
from (
select *
from `transactions`
order by `amount` desc
) t group by `user`, s
but I want to limit the sum only on the top 10 amounts.
Is it possible to do that with plain sql?
Yes, use limit and don't group by sum:
select `user`
, sum(`amount`) as s
from (
select *
from `transactions`
order by `amount` desc
limit 10
) t group by `user`

How to get first and last row for every column

input
DATE TRANSACTION TYPE
may01 22 ATM
jun18 34 ATM
Aug14 38 NB
jul18 46 NB
Sep11 29 NB
Dec21 70 NB
jan02 46 MobileB
Jun19 20 MobileB
Sep13 81 MobileB
HOW TO GET FIRST AND LAST ROW FOR EACH COLUMN LIKE
TYPE Start_DATE End_DATE
ATM may01 jun18
NB Aug14 Dec21
MobileB jan02 Sep13
IN this output have to get first date and last date group by TYPE.PLEASE HELP ME
Before you massively overhauled your question, I would have suggested:
SELECT 'COL1' AS `COL_NAMES`,(SELECT `c1` as `START_ROW` FROM `tbl` WHERE !ISNULL(`c1`) ORDER BY c1 ASC LIMIT 1) AS `ROW_START`,(SELECT `c1` as `END_ROW` FROM `tbl` WHERE !ISNULL(`c1`) ORDER BY c1 DESC LIMIT 1) AS `ROW_END`
UNION ALL
SELECT 'COL2' AS `COL_NAMES`,(SELECT `c2` as `START_ROW` FROM `tbl` WHERE !ISNULL(`c2`) ORDER BY c2 ASC LIMIT 1) AS `ROW_START`,(SELECT `c2` as `END_ROW` FROM `tbl` WHERE !ISNULL(`c2`) ORDER BY c2 DESC LIMIT 1) AS `ROW_END`
UNION ALL
SELECT 'COL3' AS `COL_NAMES`,(SELECT `c3` as `START_ROW` FROM `tbl` WHERE !ISNULL(`c3`) ORDER BY c3 ASC LIMIT 1) AS `ROW_START`,(SELECT `c3` as `END_ROW` FROM `tbl` WHERE !ISNULL(`c3`) ORDER BY c3 DESC LIMIT 1) AS `ROW_END`
UNION ALL
SELECT 'COL4' AS `COL_NAMES`,(SELECT `c4` as `START_ROW` FROM `tbl` WHERE !ISNULL(`c4`) ORDER BY c4 ASC LIMIT 1) AS `ROW_START`,(SELECT `c4` as `END_ROW` FROM `tbl` WHERE !ISNULL(`c4`) ORDER BY c4 DESC LIMIT 1) AS `ROW_END`
Assuming a table like:
CREATE TABLE IF NOT EXISTS `tbl` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` int(11) DEFAULT NULL,
`c4` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tbl` (`c1`, `c2`, `c3`, `c4`) VALUES
(1, 30, 89, 34),
(2, 49, 76, 44),
(NULL, 52, 90, NULL),
(NULL, NULL, 16, NULL);
I can't give you an exact answer, now, with your new data, now, but my answer here should bring you pretty close, you'd just need to fix a few things like the column names, the table name. My !ISNULL(...) logic is fine if you're testing for the first and last non-NULL values, which includes the empty string. If you're testing for the empty string instead, use LENGTH(...)=0 instead, or a combination if both are possible: (!ISNULL(...) AND LENGTH(...)>0)
You can use GROUP_CONCAT and SUBSTRING_INDEX to get the first and last rows like below
select type,
SUBSTRING_INDEX(GROUP_CONCAT(CAST(date AS CHAR) ORDER BY date), ',', 1 ) as Start_date,
SUBSTRING_INDEX(GROUP_CONCAT(CAST(date AS CHAR) ORDER BY date DESC), ',', 1 ) as End_date
from test
group by type;
Check SQL Fiddle DEMO here.
the below code works fine , first i have converted date in to date format
select *,str_to_date(date,"%m/%d/%Y " ) as dat from tab3 ;
SELECT TYPE,MIN(DAT) AS SD,MAX(DAT) AS ED FROM A GROUP BY TYPE;
In SQL there is predefined functions for fetching the First and last row records based on column names
SELECT FIRST(column_name) FROM table_name;
SELECT LAST(column_name) FROM table_name;
In MySQL
SELECT column_name FROM table_name
ORDER BY column_name ASC
LIMIT 1;
SELECT column_name FROM table_name
ORDER BY column_name DESC
LIMIT 1;
select
*
from
(select * from application, (SELECT #rownums:=0) r order by (#rownum := #rownum + 1) asc limit 1) a1
union
select
*
from
(select * from application, (SELECT #rownum:=0) r1 order by (#rownum := #rownum + 1) desc limit 1) a2;

Get rid of slow subquery

I have a database of connections to my server, currently with 2,300,000 rows.
I run the following query to find connections by a user, removing duplicates if the nick/ip/client_id are the same.
SELECT
`nick`,
INET_NTOA(`ip`) as `ip`,
HEX(`client_id`) as `client_id`,
UNIX_TIMESTAMP(`date`) as `date`
FROM
(SELECT * FROM `joins` ORDER BY `date` DESC) as `sub`
WHERE
`nick` LIKE '%nick%'
-- Can also be things like this:
-- `ip` & INET_ATON('255.255.0.0') = INET_ATON('123.123.0.0')
GROUP BY
`nick`,
`ip`,
`client_id`
ORDER BY
`date` DESC
LIMIT 500
Why do I use a subquery in the first place? To get the latest date value when using GROUP BY.
I think you've misunderstood the role of ORDER BY and GROUP BY in this query. In order to get the latest date per nick,ip,client_id you would write the query as follows:
SELECT
`nick`,
INET_NTOA(`ip`) as `ip`,
HEX(`client_id`) as `client_id`,
MAX(UNIX_TIMESTAMP(`date`)) as `date`
FROM
`joins`
WHERE
`nick` LIKE '%nick%'
-- Can also be things like this:
-- `ip` & INET_ATON('255.255.0.0') = INET_ATON('123.123.0.0')
GROUP BY
`nick`,
`ip`,
`client_id`
ORDER BY
`date` DESC
LIMIT 500
There is no need for a subquery at all. This code groups the data and then returns the maximum value of
UNIX_TIMESTAMP(`date`)
as date.

Select distinct column

I have the following MYSQL:
SELECT DISTINCT(`user_id`), `type`, `link`, `add_text`
FROM `activity` WHERE `id` != 0 AND `type` !=6 AND (`type` = 4 OR `type` = 5)
ORDER BY `id` DESC LIMIT 4
I only want unique user_ids but I am getting repetitions in my sql results. What is the correct modification to make to this sql so that no repetitions of user_ids
If you don't care about the types, links or add text for each user you could use min/max and group by.
SELECT user_id, max(type), max(link), max(add_text)
FROM activity
WHERE id != 0 A
AND type in (4,5)
Group by User_Id
ORDER BY id DESC LIMIT 4
If you do care you could group_concat the type, link and add text
SELECT user_id, Group_Concat(type), Group_Concat(link), Group_Concat(add_text)
FROM activity
WHERE id != 0 A
AND type in (4,5)
Group by User_Id
ORDER BY id DESC LIMIT 4
edied group by shoudl only be on user_ID
SELECT GROUP_CONCAT(DISTINCT `user_id`) user_ids, `type`, `link`, `add_text`
FROM `activity`
WHERE `id` != 0 AND `type` IN (4,5)
GROUP BY `type`, `link`, `add_text` DESC LIMIT 4;