ORDER BY complex - mysql

I've a mysql_query: select * from table ORDER BY v1, v2 ASC
Can be made a query to sort v1, v2 as below ?
+---------------+-----------------------+------+-----+
| id | name | v1 | v2 |
+---------------+-----------------------+------+-----+
| 1 | a | 1 | A |
| 2 | a | 2 | B |
| 3 | a | 3 | C |
| 4 | a | 1 | A |
| 5 | a | 2 | B |
| 6 | a | 3 | C |
| 7 | a | 1 | A |
| 7 | a | 2 | B |
| 7 | a | 3 | C |
+---------------+-----------------------+------+-----+
SQL fiddle

You need another column to sort like that. You have to tell MySQL why ids 1,2,3 come before 4,5,6. If you have another column that is e.g. 1 for 1,2,3, 2 for 4,5,6 etc, you can sort with:
ORDER BY missing_col, v1, v2

You can try this:
Select id, name, v1, v2, (v1 + ASCII(v2)) as mySum
from table
order by mySum
ASCII http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_ascii

Related

mysql table ordering incorrect with group by and order by

table 1: forum_threads
+-----+------+-------+
| id | title| status|
+-----+------+-------+
| 1 | a | 1 |
| 2 | b | 1 |
| 3 | c | 1 |
| 4 | d | 1 |
| 5 | e | 1 |
| 6 | f | 1 |
+-----+------+-------+
table 2: forum_comments
+-----+----------+--------------------+
| id | thread_id| comment |
+-----+----------+--------------------+
| 1 | 4 | hai |
| 2 | 4 | hello |
| 3 | 2 | welcome |
| 4 | 2 | whats your name |
| 5 | 6 | how are you |
| 6 | 5 | how old are you |
| 7 | 5 | good |
+-----+----------+--------------------+
wanted output
+-----------+----------+-----------------+
| thread_id | title | comment_count |
+-----------+----------+-----------------+
| 5 | e | 2 |
| 6 | f | 1 |
| 2 | b | 2 |
| 4 | d | 2 |
+-----------+----------+-----------------+
my Query
SELECT forum_threads.*,forum_comments.*,count(forum_comments.id) as comment_count
FROM forum_comments
LEFT JOIN forum_threads ON forum_comments.thread_id = forum_threads.id
GROUP BY forum_threads.id
ORDER BY forum_comments.id desc
Here I am trying to get the titles by the latest comment.
when I give ORDER BY forum_comments.id this returns the wrong order.
I need to order by the latest comments in the forum_comments table.
this query returns the wrong order please help me to find out the correct order.
how could I solve this easily?
This query should give you the expected result:
select t2.thread_id, t1.title, t2.comment_count from forum_threads as t1,
(SELECT id, thread_id, count(comment) as comment_count from forum_comments group by thread_id) as t2
where t1.id = t2.thread_id order by t2.id desc;
Instead of using forum_threads.* and forum_comments.* can you give specific column names and try.
If that doesn't work you should try explicitly assigning primary and foreign keys.

mysql fill missing values with 0

I have a mysql query that sometimes results in missing values. For my dashboard I'd like to fill those values, but would prefer to avoid build dummy tables if I can.
query:
SELECT COUNT(Comms_Timestamp) as call_count,DAYOFWEEK(Comms_Timestamp) as bucket
FROM tblTest GROUP BY bucket;
results in
+------------+--------+
| call_count | bucket |
+------------+--------+
| 4 | 1 |
| 7 | 2 |
| 7 | 3 |
| 1 | 5 |
| 6 | 6 |
| 1 | 7 |
+------------+--------+
In the above example you can see bucket 4 is missing. I consider the method where the join is to a select union array, however since both fields are aggregates, I'm not sure how to go about it.
test data is
+---------------------+
| Comms_Timestamp |
+---------------------+
| 2018-12-24 06:04:05 |
| 2018-12-24 12:18:39 |
| 2018-12-21 04:24:31 |
| 2018-12-21 08:32:44 |
| 2018-12-30 01:41:06 |
| 2018-12-30 01:53:00 |
| 2018-12-30 01:53:39 |
| 2018-12-30 02:00:01 |
| 2018-12-17 15:55:03 |
| 2018-12-17 16:04:12 |
| 2018-12-17 16:05:41 |
| 2018-12-17 16:07:43 |
| 2018-12-17 16:10:25 |
| 2018-12-18 14:03:22 |
| 2018-12-18 14:03:29 |
| 2018-12-18 14:10:19 |
| 2018-12-18 14:10:29 |
| 2018-12-18 14:10:31 |
| 2018-12-18 14:10:47 |
| 2018-12-18 14:10:55 |
| 2018-12-20 08:21:07 |
| 2018-12-28 11:03:59 |
| 2018-12-28 12:06:40 |
| 2018-12-28 12:15:01 |
| 2018-12-28 14:29:24 |
| 2019-01-05 13:33:43 |
+---------------------+
Since you are using mysql and don't have access to the seq_ option, here is an alternative way:
SELECT A.x AS bucket, IF(ISNULL(COUNT(t2.Comms_Timestamp)), 0, COUNT(t2.Comms_Timestamp)) AS call_count FROM
(select 1 x union select 2 union select 3 union select 4 union select 5 union select 6 union select 7) AS A
LEFT JOIN tblTest AS t2 ON DAYOFWEEK(t2.Comms_Timestamp) = A.x
GROUP BY bucket
ORDER BY bucket;
It may not be the prettiest option but will do what you need.
Here is a db fiddel link: db<>fiddle
If you are using MariaDB there is their Sequence Storage Engine
There is no create needed for this table, however the maximum value must be known.
select version();
| version() |
| :------------------------------------------ |
| 10.3.11-MariaDB-1:10.3.11+maria~stretch-log |
create table bob (a int)
✓
insert into bob values (4),(2)
✓
select * from seq_1_to_5
| seq |
| --: |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
SELECT s.seq, bob.a
FROM seq_1_to_5 s
LEFT JOIN bob
ON bob.a = s.seq
ORDER BY s.seq
seq | a
--: | ---:
1 | null
2 | 2
3 | null
4 | 4
5 | null
db<>fiddle here
You can use IFNULL() function in MYSQL:
SELECT IFNULL(COUNT(C.Comms_Timestamp),0) as call_count,IFNULL(DAYOFWEEK(C.Comms_Timestamp),0) as bucket
FROM tblCommunication as C LEFT JOIN tblCareTeam as CT on C.id_Case = CT.id_Case
GROUP BY CT.id_Site,bucket
HAVING CT.id_Site=8;

how to group selection from other table as one column in sql?

here is two tables:
a:
+-----+------------------------+
| id | conten |
+-----+------------------------+
| 1 | q. |
| 2 | q. |
| 3 | s. |
| 4 | g |
| 1 | a |
| 2 | a |
+-----+------------------------+
b:
+-----+------------------------+
| id | type |
+-----+------------------------+
| 1 | I. |
| 2 | II. |
| 3 | III. |
| 4 | IV |
| 5 | V |
| 6 | VI |
+-----+------------------------+
Is there a way to select from a and b so that for one id 2, there will be one additional field that groups all content from that id? the select result should be something like this:
+-----+------------------------+-----------+
| id | type | contents |
+-----+------------------------+-----------+
| 2 |I. | q,a |
+-----+------------------------+-----------+
Edited
btw, if there is a way to do it by sqlahcmey, that would be sweet.
SELECT b.id, b.type, IFNULL(GROUP_CONCAT(a.conten), '') AS contents
FROM b
LEFT JOIN a ON a.id = b.id
GROUP BY b.id
See How do I write a group_concat function in sqlalchemy? for how to translate GROUP_CONCAT to SQLAlchemy.

count record from two tables which has no relation

I have two tables tbl_user1 and tbl_user2 both are field name are same but there is no relation between that tables now I want to find total referred count from both table for example...
tbl_user1
-----------------------
UID | referenceBy | firstName | lastName | emailAddress
----------------------------------------------------------------------------
1 | NULL | aa1 | ab1 | aa1#email.com
2 | aa1#email.com | aa2 | ab2 | aa2#email.com
3 | NULL | aa3 | ab3 | aa3#email.com
4 | aa2#email.com | aa4 | ab4 | aa4#email.com
5 | aa2#email.com | aa5 | ab5 | aa5#email.com
6 | bb1#email.com | aa6 | ab6 | aa6#email.com
7 | bb2#email.com | aa7 | ab7 | aa7#email.com
8 | bb3#email.com | aa8 | ab8 | aa8#email.com
9 | bb3#email.com | aa9 | ab9 | aa9#email.com
and second one table is somthing like...
tbl_user2
-----------------------
UID | referenceBy | firstName | lastName | emailAddress
----------------------------------------------------------------------------
1 | NULL | bb1 | bc1 | bb1#email.com
2 | bb1#email.com | bb2 | bc2 | bb2#email.com
3 | NULL | bb3 | bc3 | bb3#email.com
4 | bb3#email.com | bb4 | bc4 | bb4#email.com
5 | bb2#email.com | bb5 | bc5 | bb5#email.com
6 | bb1#email.com | bb6 | bc6 | bb6#email.com
7 | aa2#email.com | bb7 | bc7 | bb7#email.com
8 | aa3#email.com | bb8 | bc8 | bb8#email.com
9 | bb5#email.com | bb9 | bc9 | bb9#email.com
now, as you can see there is no relation between these two tables and I want result like following..
MAIN_RESULT_THAT_I_WANT
-----------------------
referenceEmail | referenceEmailCount
----------------------------------------------------------------------------
aa1#email.com | 1
aa2#email.com | 3
aa3#email.com | 1
aa4#email.com | 0
aa5#email.com | 0
aa6#email.com | 0
aa7#email.com | 0
aa8#email.com | 0
aa9#email.com | 0
bb1#email.com | 3
bb2#email.com | 2
bb3#email.com | 3
bb4#email.com | 0
bb5#email.com | 1
bb6#email.com | 0
bb7#email.com | 0
bb8#email.com | 0
bb9#email.com | 0
here in result all emailAddress of all user and total of how many user(s) registered by that particular emailAddress.
I am guessing that the result you want is just copy and pasted since it seems inaccurate. Like HoneyBadger says it is strange that aa6 is missing and still in the result, that indicates you have another list you are not telling us about? Or you just write the result in notepad...
If you just want a list of emails and count this will work:
select referenceBy, count(1) as referenceEmailCount from (
select referenceBy from tbl_user1
union all
select referenceBy from tbl_user2
) as t
group by referenceBy
Otherwise give us more info if this is not what you need.
Since the schema is same for 2 tables so you can perform union to get combined results and can perform an outer query to get the total count.
select referenceEmail, count(*) as referenceEmailCount from (
select * from table1
union all
select * from table2
) as alias
group by alias.referenceEmail

Mysql Query for Combinations

can anyone please guide me with writing MySQL query for following scenario.
The data in table is like this,
Table Name: Vals
V1 | V2 | V3 |
+-----------+----+---------+
| 143 | 1 | 1 |
| 2003 | 2 | 6 |
I want result to be like this which is basically Combinations of columns with particular Column constant.
V1 | V2 | V3 |
+-----------+----+---------+
| 143 | 1 | 1 |
| 143 | 1 | 6 |
| 143 | 2 | 1 |
| 143 | 2 | 6 |
| 2003 | 1 | 1 |
| 2003 | 1 | 6 |
| 2003 | 2 | 1 |
| 2003 | 2 | 6 |
You need to use something like this do get all combinations
SELECT DISTINCT a.V1,
b.V2,
c.V3
FROM Vals a,
Vals b,
Vals c
To get it sorted then you add ORDED BY and then query looks like
SELECT DISTINCT a.V1,
b.V2,
c.V3
FROM Vals a,
Vals b,
Vals c
ORDER BY 1,
2,
3
Tested it on my table and it worked, hope it helps you.