special character that comes last in alphabetical order sql - mysql

I need to put a record at last of the result set ordered by a column field in ascending order.
LIKE:
SELECT "#TOTAL"...
Which is a user-defined column value.
Here's what I am trying to do:
SELECT cnt.name as Client, NULL, NULL, NULL, ', #COL_SUM, '
FROM
task as tsk
LEFT JOIN client cnt
ON tsk.client_id = cnt.id
GROUP BY tsk.client_id
UNION ALL
SELECT "#TOTAL#",NULL,NULL,NULL, ', #COL_SUM, '
FROM task as tsk
ORDER BY Client ASC
This returns result set as:
Client | ... | Admin | Intern | ..
---------------------------------------
#TOTAL# | ... | 4 | 2 | .. <-- this row here is grand total
A | ... | 1 | | ..
B | ... | 1 | 1 | ..
C | ... | 2 | 1 | ..
I want the #TOTAL# row to be at last.
What character, except z, comes at last in alphabetical order?

Just add your condition to the ORDER BY clause:
order by Client = '#TOTAL#', Client

You could add another constant column to the individual queries that indicate if it's a total or a regular row and order by that first.
SELECT *
FROM (SELECT 0 first_order,
cnt.name client,
...
UNION ALL
SELECT 1 first_order,
'#TOTAL#' client,
...) x
ORDER BY first_order,
client;

Try this variant of code.
For mysql:
SELECT 0 as [OrderBy], cnt.name as Client, NULL, NULL, NULL, ', #COL_SUM, '
FROM
task as tsk
LEFT JOIN client cnt
ON tsk.client_id = cnt.id
GROUP BY tsk.client_id
UNION ALL
SELECT 1 , "#TOTAL#",NULL,NULL,NULL, ', #COL_SUM, '
FROM task as tsk
ORDER BY [ORDERBY], cLIENT_ID
For sql server
SELECT * FROM (
SELECT TOP 100 PERCENT cnt.name as Client, NULL, NULL, NULL, ', #COL_SUM, '
FROM
task as tsk
LEFT JOIN client cnt
ON tsk.client_id = cnt.id
GROUP BY tsk.client_id
ORDER BY TSK.CLIENT_ID) AS DATA
UNION ALL
SELECT "#TOTAL#",NULL,NULL,NULL, ', #COL_SUM, '
FROM task as tsk
Since you are not able to apply order by in the first part of your query, so there is a method to do so, top 100 percent, and you can apply order by clause in your inner query or sub query.
Hope this helps.

Related

MySQL Query with the count, group by

Table: statistics
id | user | Message
----------------------
1 | user1 |message1
2 | user2 |message2
3 | user1 |message3
I am able to find the count of messages sent by each user using this query.
select user, count(*) from statistics group by user;
How to show message column data along with the count? For example
user | count | message
------------------------
user1| 2 |message1
|message3
user2| 1 |message2
You seem to want to show Count by user, which message sent by user.
If your mysql version didn't support window functions, you can do subquery to make row_number in select subquery, then only display rn=1 users and count
CREATE TABLE T(
id INT,
user VARCHAR(50),
Message VARCHAR(100)
);
INSERT INTO T VALUES(1,'user1' ,'message1');
INSERT INTO T VALUES(2,'user2' ,'message2');
INSERT INTO T VALUES(3,'user1' ,'message3');
Query 1:
SELECT (case when rn = 1 then user else '' end) 'users',
(case when rn = 1 then cnt else '' end) 'count',
message
FROM (
select
t1.user,
t2.cnt,
t1.message,
(SELECT COUNT(*) from t tt WHERE tt.user = t1.user and t1.id >= tt.id) rn
from T t1
join (
select user, count(*) cnt
from T
group by user
) t2 on t1.user = t2.user
) t1
order by user,message
Results:
| users | count | message |
|-------|-------|----------|
| user1 | 2 | message1 |
| | | message3 |
| user2 | 1 | message2 |
select user, count(*) as 'total' , group_concat(message) from statistics group by user;
You could join the result of your group by with the full table (or vice versa)?
Or, depending on what you want, you could use group_concat() using \n as separator.
Use Group_concat
select user, count(0) as ct,group_concat(Message) from statistics group by user;
This will give you message in csv format
NOTE: GROUP_CONCAT has size limit of 1024 characters by default in mysql.
For UTF it goes to 1024/3 and utfmb4 255(1024/4).
You can use group_concat_max_len global variable to set its max length as per need but take into account memory considerations on production environment
SET group_concat_max_len=100000000
Update:
You can use any separator in group_concat
Group_concat(Message SEPARATOR '----')
Try grouping with self-join:
select s1.user, s2.cnt, s1.message
from statistics s1
join (
select user, count(*) cnt
from statistics
group by user
) s2 on s1.user = s2.user

Concatenate results from SQL query base on another column

SELECT DISTINCT * FROM ( SELECT hostname, table2.user-id, table2.user-team from
INNER JOIN table2 on table1.id = table2.id)
So at the moment my SQL query outputs this:
hostname user-id user-team
a 1 alpha
a 2 beta
b 3 beta
c 4 alpha
c 1 null
c 3 alpha
but what I want is something like this:
hostname user-id user-team
a 1, 2 alpha, beta
b 3 beta
c 4, 1, 3 alpha
I'm trying to use a GROUP BY hostname statement at the end of my query, and a GROUP_CONCAT(DISTINCT user_id SEPARATOR ', '), GROUP_CONCAT(DISTINCT user_team SEPARATOR ', '),
But this then only returns the first hostname result and all the values possible for the user-id and team-id. I feel like I'm close, but I can't quite get it. Any help?
(At present it returns)
hostname user-id user-team
a 1,2,3,4 alpha, beta
with this as the SQL query
SELECT DISTINCT *
FROM ( SELECT hostname,
GROUP_CONCAT(DISTINCT table2.user-id SEPARATOR(', '),
GROUP_CONCAT(DISTINCT table2.team-id SEPARATOR(', ')
from table1
INNER JOIN table2 on table1.id = table2.id)
GROUP BY hostname
Although the queries arean't 100% accurate, that is the logic in them (they just contain far more columns in the real world problem I have.)
I think you miss the GROUP BY
SQL DEMO
SELECT hostname,
GROUP_CONCAT(DISTINCT user_id SEPARATOR ', ') as users,
GROUP_CONCAT(DISTINCT user_team SEPARATOR ', ') as teams
FROM Table1
GROUP BY hostname
OUTPUT
| hostname | users | teams |
|----------|---------|-------------|
| a | 1, 2 | alpha, beta |
| b | 3 | beta |
| c | 4, 1, 3 | alpha |
EDIT: After you edit your question, the problem was you put the GROUP BY outside of the subquery

MySQL Select only one row from second table, for each ID in first table

I have two tables in relation connected with primary and foreign key.
In the first table I have a server list with attributes (id, name, ip,...).
In the second table I want to insert in future Update-Informations (id, server_id, last_update, next_update,...).
Now I want to show in my GUI the Server-Attrinbutes from first table and only the last entry from second table for each server with equals server_id.
Table 1:
id
name
ip
description
.
.
Table 2:
id
server_id
last_update
next_update
.
.
Here is a short example how I already tried it:
select s.id, s.name, sp.last_update, sp.next_update
from server s
left join (select * from server_updates order by server_id desc) sp
on sp.server_id = s.id
I already tried it with the statement LIMIT 1
select s.id, s.name, sp.last_update, sp.next_update
from server s
left join (select * from server_updates order by server_id desc limit 1) sp
on sp.server_id = s.id
Also I have tried to use DISTINCT
select DISTINCT s.id, s.name, sp.last_update, sp.next_update
from server s
left join (select * from server_updates order by server_id desc limit 1)
But I always got all entrys from second table
+------------+-----------------+---------------+------------+------------+
| Server0101 | Server0101_name | Server0101_ip | 2017-09-20 | 2017-10-20 |
| Server0101 | Server0101_name | Server0101_ip | 2017-10-20 | 2017-11-20 |
| Server0102 | Server0102_name | Server0102_ip | 2017-05-01 | 2017-06-01 |
I just want one row from second table for each ID from first table.
Of course I can implement this in my JAVA-Code, but can you please tell me how to do this in MySQL.
Have you tried the below one?
select s.id, s.name, sp.last_update, sp.next_update
from server s
left join (select * from server_updates where server_id =s.id order by server_id desc limit 1) sp
on sp.server_id = s.id

MySQL Find Full Name Across Two Rows

I have a MySQL table where I'm trying to find a person by his full name. The problem is that first and last name are stored on two separate rows in the table as shown here:
+-----------------+-------------+-------------+--------------+
| submit_time | form_name | field_name | field_value |
+-----------------+-------------+-------------+--------------+
| 1323463601.0947 | Online Form | firstname | Paulo |
| 1323463601.0947 | Online Form | lastname | Hill |
+-----------------+-------------+-------------+--------------+
How can I construct a query that will get a single result (if possible) by searching for Paulo Hill?
Also, the submit_time column should have the same value for both rows--that will be the one column value that is unique in the table.
You could use a self-join:
SELECT t1.submit_time, t1.field_value, t2.field_value
FROM your_table t1
INNER JOIN your_table t2 ON t2.submit_time = t1.submit_time
WHERE t1.field_name = 'firstname'
AND t1.field_value = 'Paulo'
AND t2.field_name = 'lastname'
AND t2.field_value = 'Hill'
Supposing 'paulo hill' is a single search query:
SELECT t1.*,
t2.field_value
FROM tbl t1
INNER JOIN tbl t2 ON t1.submit_time = t2.submit_time
AND t2.field_name = 'lastname'
WHERE t1.field_name = 'firstname'
AND t1.field_value || ' ' || t2.field_value = 'paulo hill'
Note: this solution is sensitive to amount of spaces between first name and last name in search query
try this:
SELECT * FROM (
SELECT submit_time, group_concat(field_value SEPARATOR ' ') AS fullname
FROM TABLE_NAME
GROUP BY `submit_time`
) AS innertable
WHERE fullname='Paulo Hill'
One alternative is to use GROUP_CONCAT if you know the order:
SELECT GROUP_CONCAT(field_value SEPARATOR ' ')
FROM tab
GROUP BY submit_time
HAVING GROUP_CONCAT(field_value ORDER BY field_id ASC) LIKE '%Paulo,Hill%'

How do I concatenate strings from a subquery into a single row in MySQL?

I have three tables:
table "package"
-----------------------------------------------------
package_id int(10) primary key, auto-increment
package_name varchar(255)
price decimal(10,2)
table "zones"
------------------------------------------------------
zone_id varchar(32) primary key (ex of data: A1, Z2, E3, etc)
table "package_zones"
------------------------------------------------------
package_id int(10)
zone_id varchar(32)
What I'm trying to do is return all the information in package table PLUS a list of zones for that package. I want the list of zones sorted alphabetically and comma separated.
So the output I'm looking for is something like this:
+------------+---------------+--------+----------------+
| package_id | package_name | price | zone_list |
+------------+---------------+--------+----------------+
| 1 | Red Package | 50.00 | Z1,Z2,Z3 |
| 2 | Blue Package | 75.00 | A2,D4,Z1,Z2 |
| 3 | Green Package | 100.00 | B4,D1,D2,X1,Z1 |
+------------+---------------+--------+----------------+
I know I could do something in PHP with the presentation layer to get the desired result. The problem is, I would like to be able to sort zone_list ASC or DESC or even use WHERE zone_list LIKE and so on. In order to do that, I need this done in MySQL.
I have NO idea how to even begin to tackle this. I tried using a subquery, but it kept complaining about multiple rows. I tried to concat the multiple rows into a single string, but evidently MySQL doesn't like this.
Thanks in advance.
UPDATE!
Here is the solution for those who are interested:
SELECT
`package`.*,
GROUP_CONCAT(`zones`.`zone` ORDER BY `zones`.`zone` ASC SEPARATOR ',' ) as `zone_list`
FROM
`package`,
`package_zones`
LEFT JOIN
(`zones`,`ao_package_zones`) ON (`zones`.`zone_id` = `package_zones`.`zone_id` AND `package_zones`.`package_id` = `package`.`package_id`)
GROUP BY
`ao_package`.`package_id`
by using the GROUP_CONCAT() function and a GROUP BY call. here's an example query
SELECT
p.package_id,
p.package_name,
p.price,
GROUP_CONCAT(pz.zone_id SEPARATOR ',') as zone_list
FROM
package p
LEFT JOIN package_zone pz ON p.package_id = pz.package_id
GROUP BY
p.package_id
you should still be able to order by zone_id s (or zone_list), and instead of using LIKE, you can use WHERE zp.zone_id = 'Z1' or something similar.
I have a customer who requested me to generate a query to use in a prestashop database to get the last year records from ps_orders, ps_customer tables; and one of those column was "The list of product ids in the order" from the ps_order_detail table. So, my query result was:
SELECT
o.id_order, o.reference,
(
SELECT
GROUP_CONCAT(od.product_id SEPARATOR ', ') AS products
FROM ps_order_detail od
WHERE od.id_order = o.id_order
GROUP BY od.id_order
) AS product_ids,
CONCAT(c.firstname, ' ', c.lastname) AS customer, o.current_state, o.payment, o.total_discounts,
o.total_discounts_tax_incl, o.total_discounts_tax_excl, o.total_paid, o.total_paid_tax_incl,
o.total_paid_tax_excl, o.total_products, o.total_products_wt, o.total_shipping, o.total_shipping_tax_incl,
o.total_shipping_tax_excl, o.carrier_tax_rate, o.total_wrapping, o.total_wrapping_tax_incl,
o.total_wrapping_tax_excl, o.invoice_number, o.delivery_number, o.valid
FROM ps_orders o
INNER JOIN ps_customer c ON c.id_customer = o.id_customer
WHERE
o.date_add <= NOW() AND o.date_add >= DATE_ADD(NOW(), INTERVAL - 12 MONTH);
Result: