How to display multiple row values into single row - php

Here my table is like this
Leave_Type Leave_Balance
CL 12
PL 10
Now i want to display my data like below
Leave_Type_CL Leave_Type_PL Leave_Balance_CL Leave_Balance_PL
CL PL 12 10

Try this:
SELECT CONCAT(
group_concat(CONVERT(Leave_Type, CHAR(2)) separator ' '),
' ',
group_concat(CONVERT(Leave_Balance, CHAR(2)) separator ' ')
) FROM Leave_Table;

Related

Combine mysql result into 1 row

table img
SELECT namaline, shift1 FROM semualine WHERE cektelatshift1 <> 'Ontime' UNION
SELECT namaline, shift2 FROM semualine WHERE cektelatshift2 <> 'Ontime' UNION
SELECT namaline, shift3 FROM semualine WHERE cektelatshift3 <> 'Ontime';
namaline
shift1
Line 1
Shift 1
Line 2
Shift 1
Line 3
Shift 1
Line 1
Shift 2
Line 2
Shift 2
Line 3
Shift 2
Line 1
Shift 3
Line 2
Shift 3
I want to combine all this result into 1 cell
myexpectation is
1 cell
Line 1 Shift 1, Line 2 Shift 1, Line 3 Shift 1, Line 1 Shift 2, Line 1 Shift 1, Line 2 Shift 2, Line 1 Shift 3, Line 2 Shift 3
Thank for all the answer.
Sorry, I'm still new here should show my DB and used english. I figure out the close answer.
SELECT shift1 AS shift, GROUP_CONCAT(`namaline` SEPARATOR ', ') AS 'line'
FROM semualine
WHERE cektelatshift1 <> 'Ontime'
UNION
SELECT shift2 AS shift, GROUP_CONCAT(`namaline` SEPARATOR ', ') AS 'line'
FROM semualine
WHERE cektelatshift2 <> 'Ontime'
UNION
SELECT shift3 AS shift, GROUP_CONCAT(`namaline` SEPARATOR ', ') AS 'line'
FROM semualine
WHERE cektelatshift3 <> 'Ontime';
shift
line
Shift 1
Line 1, Line 2, Line 3
Shift 2
Line 1, Line 2, Line 3
Shift 3
Line 1, Line 2
To achieve the output format you are looking for the following needs to be done
select GROUP_CONCAT(namaline, ' ', shift1) from semualine;
In GROUP_CONCAT space is needed between columns to have the space in the output as well
The repeating pattern shift1, cektelatshift1, shift2, cektelatshift2, ... is a good indication of a table that would benefit from being normalized.
Both of these queries provide a result similar to your example (cannot be the same as your example is inconsistent). They differ in whether it is the row or column which is concatenated first.
SELECT
GROUP_CONCAT(
CONCAT_WS(', ',
IF(cektelatshift1 <> 'Ontime', CONCAT_WS(' ', namaline, shift1), NULL),
IF(cektelatshift2 <> 'Ontime', CONCAT_WS(' ', namaline, shift2), NULL),
IF(cektelatshift3 <> 'Ontime', CONCAT_WS(' ', namaline, shift3), NULL)
)
SEPARATOR ', '
)
FROM semualine
WHERE NOT (cektelatshift1 = 'Ontime' AND cektelatshift2 = 'Ontime' AND cektelatshift3 = 'Ontime');
SELECT
CONCAT_WS(', ',
GROUP_CONCAT(
IF(cektelatshift1 <> 'Ontime', CONCAT_WS(' ', namaline, shift1), NULL)
SEPARATOR ', '
),
GROUP_CONCAT(
IF(cektelatshift2 <> 'Ontime', CONCAT_WS(' ', namaline, shift2), NULL)
SEPARATOR ', '
),
GROUP_CONCAT(
IF(cektelatshift3 <> 'Ontime', CONCAT_WS(' ', namaline, shift3), NULL)
SEPARATOR ', '
)
)
FROM semualine
WHERE NOT (cektelatshift1 = 'Ontime' AND cektelatshift2 = 'Ontime' AND cektelatshift3 = 'Ontime');

I need help writing a sql query to concat multiple fields

I have table with following information
id | order_id | batch_id | bucket_id | menu_id | product_id | type_id | size
1 | 1 | 1 | 1 | 1 | 1 | 1 | small
2 | 1 | 1 | 1 | 1 | 5 | 1 | small
3 | 1 | 1 | 1 | 1 | 5 | 1 | medium
I want to achieve following
order_id | batch_id | product1 | product5
1 | 1 | 1 x small| 1 x small, 1 medium
Is this possible to write a query to achieve this?
It's possible in MySQL using this kind of query:
SELECT order_id, batch_id,
GROUP_CONCAT(CASE WHEN product_id=1 THEN CONCAT(type_id,' x ', size) END) AS product1,
GROUP_CONCAT(CASE WHEN product_id=5 THEN CONCAT(type_id,' x ', size) END) AS product5
FROM table1
GROUP BY order_id, batch_id
The problem with this is that it's not dynamic so if you have hundreds, thousands of products, the query will be very hard to maintain. One possible solution in MySQL is using prepared statement. Here is an updated example after #ggordon spotted that my previous attempt show duplicates:
SET #columns := (SELECT GROUP_CONCAT(CONCAT("GROUP_CONCAT(CASE WHEN product_id=",product_id,"
THEN CONCAT(cnt,' x ', size) END)
AS product",product_id,"
"))
FROM (SELECT DISTINCT product_id FROM table1) t1);
SET #query := CONCAT('SELECT order_id, batch_id, ',#columns,'
FROM (SELECT product_id, order_id, batch_id, size, COUNT(*) cnt
FROM table1 GROUP BY product_id, order_id, batch_id, size) t1
GROUP BY order_id, batch_id');
PREPARE stmt FROM #query ;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
There are 2 variables being used in there and I named each variable to represent what is it (hopefully).
Demo fiddle
The following query would return the desired data you would need
SELECT
order_id,
batch_id,
product_id,
concat(
count(product_id),
' x ',
size
) as size_cnt
FROM
t1
GROUP BY
order_id,
batch_id,
product_id,
size;
order_id
batch_id
product_id
size_cnt
1
1
1
1 x small
1
1
5
1 x small
1
1
5
1 x medium
View working demo on DB Fiddle
However, in order to get it in the desired format, you would need to pivot the data. You could achieve this with the assistance of group_concat as shown in the sql example below:
SELECT
order_id,
batch_id,
-- we can generate from here
REPLACE(
GROUP_CONCAT(
',',
CASE
WHEN product_id=1 THEN size_cnt
END
),
',,',
','
) as product1,
REPLACE(
GROUP_CONCAT(
',',
CASE
WHEN product_id=5 THEN size_cnt
END
),
',,',
','
) as product5
-- to here. See explanation below
FROM (
SELECT
order_id,
batch_id,
product_id,
concat(
count(product_id),
' x ',
size
) as size_cnt
FROM
t1
GROUP BY
order_id,
batch_id,
product_id,
size
) t2
GROUP BY
order_id,
batch_id
order_id
batch_id
product1
product5
1
1
,1 x small
,1 x small,1 x medium
View working demo on DB Fiddle
However, as you can see, you would have to know the product_ids before hand for the desired columns.
If you are uncertain about the product ids that you will have, writing a dynamic query would be helpful here. You could start by getting all the product_ids.
I'm using the DB facade from Laravel here, however, you may use the Eloquent ORM or other methods to achieve the following:
//I have a collection of product ids i.e. `collect([1,5])` based on your example
$productIds = DB::select("select distinct product_id from t1")
->pluck('product_id');
Then generating a dynamic sql query to run on your table
$productExpression = DB::select("select distinct product_id from t1")
->pluck('product_id')
//for each product id let us return an sql expression
->map(function($productId){
return "
REPLACE(
GROUP_CONCAT(
',',
CASE
WHEN product_id=$productId THEN size_cnt
END
),
',,',
','
) as product$productId
";
})
//combine the expressions into one string
->join(",");
We can now create a combined query as
$combinedQuery="
SELECT
order_id,
batch_id,
$productExpression
FROM (
SELECT
order_id,
batch_id,
product_id,
concat(
count(product_id),
' x ',
size
) as size_cnt
FROM
t1
GROUP BY
order_id,
batch_id,
product_id,
size
) t2
GROUP BY
order_id,
batch_id;
";
//running the query to retrieve the results
$results = DB::select($combinedQuery);
Let me know if this works for you.
If you are using php with either PDO or mysqli you can get PHP to concat the fields.
$result = $db->query("SELECT * FROM TABLE");
while($row = $result->fetch_assoc()) {
//do stuff with data
$product .= $row["product_id"] . " x " . $row["size"].", ";
}

Mysql query for displaying row value as column header dynamically

my table looks ike this
dt ticker open
1 A 1.2
1 B 6
2 A 1.4
2 B 6.5
I would like it to turn out to be
dt A B
1 1.2 1.4
2 6 6.5
I tried using mysql query in below format
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(ticker= ''',
ticker,
''', open, NULL)) AS ',
ticker
)
) INTO #sql
FROM properties;
SET #sql = CONCAT('SELECT dt, ', #sql, ' FROM properties GROUP BY dt');
while executing the query in phpmyadmin I am getting below error .
Warning in .\libraries\dbi\DBIMysqli.php#436
mysqli_fetch_fields() expects parameter 1 to be mysqli_result, boolean given
can anyone help me with this ?

leading 0 not displaying in mysql table result

just concatenating two values to one column in a mysql table. First Value from mysql table and second value from PHP constant saved as define('ACCOUNTCODESUFFIX','016');.
MySql query somewhat looks like
SELECT CONCAT_WS(\' \', mbrs.firstname, mbrs.lastname) AS fullname,
CONCAT_WS(\'-\',gl.code, '.ACCOUNTCODESUFFIX.') AS code
FROM allTbls
INNER JOIN generalledgertbl gl ON (allTbls.claim_type=gl.claimtype
AND allTbls.claim_category=gl.claimtitle
AND allTbls.claimoption=gl.claimoption)
Output:
fullname | code
name1 | 12345-16
name2 | 23456-16
How to have Output like this without using LPAD()
fullname | code
name1 | 12345-016
name2 | 23456-016
This will do it, and without all that escaping that is probably causing the confusion
define('ACCOUNTCODESUFFIX','016');
$sql = "SELECT CONCAT_WS(' ', mbrs.firstname, mbrs.lastname) AS fullname,
CONCAT_WS('-',gl.code, '" . ACCOUNTCODESUFFIX . "') AS code
FROM allTbls
INNER JOIN generalledgertbl gl ON (allTbls.claim_type=gl.claimtype
AND allTbls.claim_category=gl.claimtitle
AND allTbls.claimoption=gl.claimoption)";
echo $sql;
RESULT:
SELECT CONCAT_WS(' ', mbrs.firstname, mbrs.lastname) AS fullname,
CONCAT_WS('-',gl.code, '016') AS code
FROM allTbls
INNER JOIN generalledgertbl gl ON (allTbls.claim_type=gl.claimtype
AND allTbls.claim_category=gl.claimtitle
AND allTbls.claimoption=gl.claimoption)

Use SQL to find out the highest frequency of the most common word

I am using MySQL Workbench for my application (consisting of JavaScript and PHP). I have a SQL database that contains the tweets. I would like to query what is the highest frequency of the word from the tweets(sentence). I have done research that says to use count() to query but I still unable to get what I want.
Example dataset:
tweetsID | Tweets | DateTime
1 | I can't wait to go to school tomorrow! | 2014-07-18 12:00:00
2 | My teacher saw me hanging out after school | 2014-07-18 12:20:00
3 | I had Pepper Lunch for my dinner | 2014-07-18 12:30:00
4 | Something happened in my school omg | 2014-07-18 12:40:00
5 | This project is so hard! | 2014-07-18 12:50:00
Expected output:
Words |frequency
I |2
can't |1
wait |1
to |2
school |3
tomorrow|1
! |2
my |3
had |1
teacher |1
saw |1
me |1
hanging |1
out |1
after |1
pepper |1
lunch |1
for |1
dinner |1
something|1
happened |1
in |1
omg |1
this |1
project |1
is |1
so |1
hard |1
I have create the sample data in the following link :
[ http://sqlfiddle.com/#!2/3b3f2/1 ]
Anyone can teach me or any reference for me to guide? Thank you in advance.
I think your best bet is to do this in PHP. array_count_values() comes to mind.
Try this:
$sqlresults = array(
"I can't wait to go to school tomorrow!",
"My teacher saw me hanging out after school",
"I had Pepper Lunch for my dinner",
"Something happened in my school omg",
"This project is so hard!"
);
$arr = array();
foreach ($sqlresults as $str) {
$arr = array_merge($arr, explode(' ', $str));
}
$arr = array_count_values($arr);
print_r($arr);
See demo
References:
array_count_values()
array_merge()
explode()
I would say you need to refactor your DB.
I would introduce a separate table - words (id, word) and a relation table tweet_to_word (tweet_id, word_id, word_count) where you can keep all words for each tweet.
After that it would be a simple
select count(ttw.word_count)
from tweet_to_word ttw
group by word_id
you can add ORDER BY to the select to find the most popular word
As a demonstration of how messy this could get, the following will almost do what you want in a single piece of SQL.
This firstly replace punctuation with spaces, then replaces 2 spaces with 1 space (several times). The idea of this is to give you a string which contains the words separated by a single space.
From this the number of words is calculated by comparing the length with the length with spaces replaced with nothing.
This is then cross joined with selects getting the numbers 0 to 9, which when cross joined gives you 1000 rows for each tweet, along with the numbers 0 to 999. This is then used with SUBSTRING_INDEX to get all the individual words. The number (from 0 to 999) is compared with the number of words in the tweet to avoid duplicating the last word.
Then this is just used for a normal COUNT / GROUP BY to get the word and count.
SELECT Words, COUNT(*) AS frequency
FROM
(
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(Tweets, ' ', 1 + units.i + tens.i * 10 + hundreds.i * 100), ' ', -1) AS Words
FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) hundreds
CROSS JOIN
(
SELECT Tweets,
(LENGTH(Tweets) - LENGTH(REPLACE(Tweets, ' ', ''))) + 1 AS Tweets_Words
FROM
(
SELECT TRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(Tweets, '(', ' '), ')', ' '), ',', ' '), '.', ' '), ';', ' '), ':', ' '), '?', ' '), '!', ' '), '{', ' '), '}', ' '), ' ', ' '), ' ', ' '), ' ', ' '), ' ', ' ')) AS Tweets
FROM some_tweets
) sub0
) sub1
WHERE Tweets_Words > (units.i + tens.i * 10 + hundreds.i * 100)
) sub2
GROUP BY Words
The replacement of double spaces with a single space can probably be removed, replacing it with a check that the resulting word is not '':-
SELECT Words, COUNT(*) AS frequency
FROM
(
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(Tweets, ' ', 1 + units.i + tens.i * 10 + hundreds.i * 100), ' ', -1) AS Words
FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) hundreds
CROSS JOIN
(
SELECT Tweets,
(LENGTH(Tweets) - LENGTH(REPLACE(Tweets, ' ', ''))) + 1 AS Tweets_Words
FROM
(
SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(Tweets, '(', ' '), ')', ' '), ',', ' '), '.', ' '), ';', ' '), ':', ' '), '?', ' '), '!', ' '), '{', ' '), '}', ' ') AS Tweets
FROM some_tweets
) sub0
) sub1
WHERE Tweets_Words > (units.i + tens.i * 10 + hundreds.i * 100)
) sub2
WHERE Words != ''
GROUP BY Words
SQL fiddle for it here:-
http://www.sqlfiddle.com/#!2/f28e5/1

Categories