id | p_id
--------------------------
1 | 0
2 | 0
3 | 1
4 | 2
5 | 0
6 | 7
7 | 1
8 | 0
This is above table data's, if i give
SELECT * from tablename order by `id` asc
it will bring the above result set
But my use case is i need to sort by both the id and p_id in a different way (i.e) i need to get result set by like below
id | p_id
--------------------------
1 | 0
3 | 1
7 | 1
6 | 7
2 | 0
4 | 2
5 | 0
8 | 0
let me explain briefly about that, p_id value 1 should be the next to the id 1 and that is arranged like above, it clearly show that p_id 1 and p_id 2 is next to the id 1 and 2 respectively and make sure that id 7 in order and id 6 next to id 7
If I understood you correctly , you want the order to be -> If P_id=0 then to order by ID , else, order by p_id.
You can achieve this by conditional ordering using CASE EXPRESSION :
SELECT *
FROM YourTable t
ORDER BY CASE WHEN t.pid = 0
THEN t.id
ELSE t.p_id
END ASC,
t.id
This should return you your expected results.
You need to know the relationship between the id's and since the 2 id blocks have different sort requirements you also need a helper column and a subquery.
create table t (id int, pid int)
insert into t
values
( 1 , 0),
( 2 , 0),
( 3 , 1),
( 4 , 2),
( 5 , 0),
( 6 , 7),
( 7 , 1),
( 8 , 0)
select s.id,s.pid
from
(
select case
when t.id in (1,3,7,6) then 1
else 2
end as ac
,
case
when t.id in (1,3,7,6) then pid
else id
end as sortcol
,
t.*
from t
) s
order by s.ac,s.sortcol
Result
id pid
1 0
3 1
7 1
6 7
2 0
4 2
5 0
8 0
Related
i'm trying to create an overview page for my customers and would like to show when the customer (within the last year) used a type of service (e.g. window cleaning or floor cleaning).
I tried it this way:
SELECT start, project_id, category_id, MAX(start)
FROM `time_entries`
WHERE project_id = '$project_id' AND start > '$oneyearago'
GROUP BY category_id
project_id = kind of a unique customer id
category_id = 1 for window cleaning, 2 for floor cleaning and so on
start = DATETIME when the last service started
I would like to show the LAST services, but it only shows the oldest services. What am i Doing wrong? does anyone here has a idea for me?
Thank you very much in advance.
EDIT: This is the database example
id project_id category_id start
---|------------|-----------|-------------------
1 | 1 | 1 | 2019-11-11 09:51:07
2 | 1 | 2 | 2019-11-12 09:51:07
5 | 1 | 3 | 2019-11-13 09:51:07
3 | 1 | 1 | 2020-11-11 09:51:07
4 | 1 | 2 | 2020-11-12 09:51:07
5 | 1 | 3 | 2020-11-13 09:51:07
6 | 1 | 1 | 2021-11-11 09:51:07
7 | 1 | 2 | 2021-11-12 09:51:07
I would like to see
category 1: last appointment was 2021-11-11
category 2: last appointment was 2021-11-12
category 3: last appointment was 2020-11-13
I was asking for scripts like this
CREATE TABLE time_entries (id int, project_id int, category_id int, start datetime);
INSERT INTO time_entries VALUES(1 , 1 , 1 , '2019-11-11 09:51:07'),(2 , 1 , 2 , '2019-11-12 09:51:07'), (5 , 1 , 3 , '2019-11-13 09:51:07'), (3 , 1 , 1 , '2020-11-11 09:51:07'), (4 , 1 , 2 , '2020-11-12 09:51:07'), (5 , 1 , 3 , '2020-11-13 09:51:07'), (6 , 1 , 1 , '2021-11-11 09:51:07'), (7 , 1 , 2 , '2021-11-12 09:51:07');
Now, solution to your problem. you can add date check in where clause.
SELECT T1.id, T1.start, T1.project_id, T1.category_id, T2.start
FROM time_entries T1
INNER JOIN(
SELECT category_id, MAX(start)start
FROM time_entries
WHERE project_id=1
GROUP BY category_id
)T2 ON T1.category_id=T2.category_id AND T1.start = T2.Start
ORDER BY T1.category_id
Please try below query
SELECT project_id, category_id, MAX(start) as last_datetime FROM time_entries WHERE project_id = '$project_id' GROUP BY category_id
I have the following table structure in a mysql database.
id | files | status
1 a.pdf,b.pdf,c.pdx 1
2 d.pdf,e.pdf.g.pdf 2
3 x.pdf,k.pdf,y.pdf 1
As you can see, the attachments are all stored on a single line.
My query is supposed to select all rows where status = 1 so i'm expecting the data in the following format.
1 1 a.pdf 1
2 1 b.pdf 1
3 1 c.pdf 1
4 3 x.pdf 1
5 3 k.pdf 1
6 3 y.pdf 1
Unfortunately, I am unsure which operator I can use to accomplish this. I'm aware SQL has pivot but i doubt even that can address my issue.
As a result, I would appreciate if I could get any help in the condition of the select query.
Regards
Try this:
SET #row_num = 0;
SELECT
(#row_num := #row_num + 1) ROW_NUM,
id,
SUBSTRING_INDEX(SUBSTRING_INDEX(files, ',', idx), ',', -1) FileName,
status
FROM
test
JOIN
(SELECT 1 idx UNION ALL SELECT 2 idx UNION ALL SELECT 3 idx UNION ALL SELECT 4 idx UNION ALL SELECT 5 idx) idxs
on idxs.idx - 2 < LENGTH(files) - LENGTH(REPLACE(files, ",", ""))
WHERE status = 1
;
Just add as many indexes as your max count of files in a string.
Note that there should be no comma fater last filename. This is magic -2 is responsible for.
Consider the following...
I have a table (ints) of integers (0-9)...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,files VARCHAR(100) NOT NULL
,status INT NOT NULL
);
INSERT INTO my_table VALUES
(1,'a.pdf,b.pdf,c.pdx',1),
(2,'d.pdf,e.pdf,g.pdf',2),
(3,'x.pdf,k.pdf,y.pdf',1);
SELECT DISTINCT id
, SUBSTRING_INDEX(SUBSTRING_INDEX(files,',',i2.i*10+i1.i+1),',',-1) file
, status
FROM my_table
, ints i1
, ints i2
WHERE status = 1
ORDER
BY id, i2.i*10+i1.i;
+----+-------+--------+
| id | file | status |
+----+-------+--------+
| 1 | a.pdf | 1 |
| 1 | b.pdf | 1 |
| 1 | c.pdx | 1 |
| 3 | x.pdf | 1 |
| 3 | k.pdf | 1 |
| 3 | y.pdf | 1 |
+----+-------+--------+
given the following table:
id (desc) | amount
------------------
9 | 3
8 | 2
7 | 1 <- RETURN THIS ROW
6 | 0
5 | 1
4 | 0
3 | 2
2 | 1
1 | 0
I need to return only one row - that one with the id 7
Rules:
- the most recent entry have an amount bigger than 0
- should return the row after the first amount 0 occurence
That way if I have:
id (desc) | amount
------------------
4 | 0
3 | 0
2 | 1
1 | 0
It will not show any row.
You can use window functions:
select t.*
from (select t.*,
max(case when amount = 0 then id end) over () as last_0_id
from t
) t
where id > last_0_id
order by id asc
limit 1;
Or, without window functions:
select t.*
from t join
(select max(t2.id) as id
from t t2
where t2.amount = 0
) t2
on t.id > t2.id
order by id asc
limit 1;
Here is a db<>fiddle
This is probably faster than using lead(), actually.
I have a trouble with my code. I want to get only one rows each conditions in MySQL.
I have a table like that:
ID - Position - Content
1 2 abc
2 1 def
3 1 ghk
4 3 pol
5 2 lop
6 4 gty
So I want the result returned like: position = 1 -> highest id row then pass to position = 2 -> highest id row. I have no idea to code it.
Use a sub query to test the id
drop table if exists t;
create table t
(ID int, Position int, Content varchar(3));
insert into t values
(1 , 2 , 'abc'),
(2 , 1 , 'def'),
(3 , 1 , 'ghk'),
(4 , 3 , 'pol'),
(5 , 2 , 'lop'),
(6 , 4 , 'gty');
select t.*
from t
where t.id = (select min(id) from t t1 where t1.position = t.position);
+------+----------+---------+
| ID | Position | Content |
+------+----------+---------+
| 1 | 2 | abc |
| 2 | 1 | def |
| 4 | 3 | pol |
| 6 | 4 | gty |
+------+----------+---------+
4 rows in set (0.00 sec)
try this query..
SELECT DISTINCT * FROM table-name ORDER BY ID ASC;
DISTINCT operates on a single column. DISTINCT for multiple columns is not supported.
same column cant not print
And
order by id asc use and all record print 1 - n means minimum id
you can try like below query
SELECT t.*
FROM t
WHERE t.id IN (SELECT min(id) FROM t GROUP BY position);
i would like construct a query to count the number of student who don't have number 0.
assuming i have 2 tables
students
*student_id
*name
Number
*number_id
*student_id
*number
| Student 1 |
1
1
1
1
| Student 2 |
1
1
1
1
| Student 3 |
1
0
1
0
|Student 4 |
0
1
1
1
So the result should be. student without zero = 2
student with zero = 2
This answer assumes that your table has the following structure:
id | value
1 | 1
1 | 1
1 | 1
1 | 1
2 | 1
etc...
SELECT id
FROM yourTable
GROUP BY id
HAVING SUM(CASE WHEN value = 0 THEN 1 ELSE 0 END) = 0
Something like this might return the specified result:
SELECT CONCAT('student without zero = '
, ( SELECT SUM(1)
FROM ( SELECT t.`some_identifier`
FROM `sometable` t
GROUP BY t.`some_identifier`
HAVING SUM(IF(t.`some_col`=0,1,0)) = 0
)
)
, '\n'
, 'student with zero = '
, ( SELECT SUM(1)
FROM ( SELECT z.`some_identifier`
FROM `sometable` z
WHERE z.`some_col` = 0
GROUP BY z.`some_identifier`
)
)
) AS `result`
Just replace some_table with the name of the table, some_col with the name of the column that contains the 1 and 0 values, and some_identifier with the column that contains the Student 1, Student 2, etc. values.
This should return a single row, something like this:
result
--------------------------------
student without zero = 2
student with zero = 2