Concatenating 2 values from 2 consecutive recordsets | MySQL - mysql

I want to get the data from 1 SQL query of a table with 2 values
select c from tmp;
c
foo
bar
2 rows in set (0.00 sec)
The returned data I need is <foo,bar>
Concat does not do this nor does any string function I can find. I can SUM integers from 2 lines. Why can't I retrieve the string values likewise?

you can use GROUP_CONCAT() function to get values together.
This will combine all the string values separated by comma

Perhaps you need a group_concat() in MYSQL.
Noticing that you need in MYSQL here a sample:
* SQLFIDDLE demonstration
Select department, group_concat(name,',') as nameList
from foo
group by department
;
Results:
Department NameList
D1 John, Mary
D2 Tim, Dan, Jack
D3 Kate, Felix
Following is a method to use in TSQL:
You can try the following sample code and adjust it for your table/columns:
SELECT department, namelist = STUFF(
(SELECT ','+ Name FROM foo B
WHERE b.department = a.department FOR XML PATH('')) , 1 , 1 , '' )
FROM foo A
Or else you may do a CTE.

Related

how to use concat, like and subconsultas with where?

SELECT asset_tag.asset_id, LEFT(asset_tag,SUBSTRING(asset_tag)-1 AS 'ETIQ'
from (SELECT DISTINCT S2.asset_id + ',' AS etiquetas
(SELECT S1.tag_id
FROM asset_tag AS S1
WHERE S1.tag_id
ORDER BY S1.tag_id
FOR XML PATH (''),TYPE
).VALUE('TEXT(1)`[1]','ninteger(MAX')[aset_tag] FROM asset_tag AS S2 ) asset_tag;
I have to group by asset and the asset 1 have in one column 1,2,3,4,5 or the tag that it have
how to use heidisql functions, on dbforge? I know but here not I use heidisql version 12. and is my first time working with this
The objective is that the source table that has two columns, group by column 1 and that a new column indicate separated by commas what column 1 has in column 2 (of origin).
columna 1 - 1 1 2 2 3 3 4 4
columna 2 - a b c a d a f g
and in a new column or table 1 - a b / 2 - b c
I see this answer on this page: https://stackoverflow.com/a/545672/20100117 But i donĀ“t know what mean "st1" or [text()] the alias?
SELECT Main.SubjectID,
LEFT(Main.Students,Len(Main.Students)-1) As "Students" FROM
(
SELECT DISTINCT ST2.SubjectID,
(
SELECT ST1.StudentName + ',' AS [text()]
FROM dbo.Students ST1
WHERE ST1.SubjectID = ST2.SubjectID
ORDER BY ST1.SubjectID
FOR XML PATH (''), TYPE
).value('text()[1]','nvarchar(max)') [Students]
FROM dbo.Students ST2
) [Main]
If you use HeidiSQL, you can use the completion proposal to help finding the right syntax for the various functions. Just type some first characters and press Ctrl+Space:
Here's a basic example of how SUBSTRING() works:
SELECT SUBSTRING(name, 2, 3) FROM mytable;
How to concatenate rows of the same column in PostgreSQL?
Given that you want to concatenate rows of the same column, and not different columns (which is what you do when using CONCAT_WS()), what you would really be looking for is to use the ARRAY_AGG aggregation function within the ARRAY_TO_STRING function.
Documentation: https://www.postgresql.org/docs/13/functions-array.html
solution:
SELECT
a.asset_id, ARRAY_TO_STRING(ARRAY_AGG(a.tag_id), ',') AS etiqueta
FROM public.asset_tag AS a
GROUP BY a.asset_id;
Result:
on asset_id 1 | 1,3,5 tag_id
on asset_id 6 | 1,2 tag_id
If you insert this:
CREATE TABLE asset_tag ( asset_id INT,tag_id INT);
INSERT INTO asset_tag VALUES (1,1);
INSERT INTO asset_tag VALUES (1,3);
INSERT INTO asset_tag VALUES (1,5);
INSERT INTO asset_tag VALUES (6,1);
INSERT INTO asset_tag VALUES (6,2);
thanks to the person who gave me this answer .

select one row multiple time when using IN()

I have this query :
select
name
from
provinces
WHERE
province_id IN(1,3,2,1)
ORDER BY FIELD(province_id, 1,3,2,1)
the Number of values in IN() are dynamic
How can I get all rows even duplicates ( in this example -> 1 ) with given ORDER BY ?
the result should be like this :
name1
name3
name2
name1
plus I shouldn't use UNION ALL :
select * from provinces WHERE province_id=1
UNION ALL
select * from provinces WHERE province_id=3
UNION ALL
select * from provinces WHERE province_id=2
UNION ALL
select * from provinces WHERE province_id=1
You need a helper table here. On SQL Server that can be something like:
SELECT name
FROM (Values (1),(3),(2),(1)) As list (id) --< List of values to join to as a table
INNER JOIN provinces ON province_id = list.id
Update: In MySQL Split Comma Separated String Into Temp Table can be used to split string parameter into a helper table.
To get the same row more than once you need to join in another table. I suggest to create, only once(!), a helper table. This table will just contain a series of natural numbers (1, 2, 3, 4, ... etc). Such a table can be useful for many other purposes.
Here is the script to create it:
create table seq (num int);
insert into seq values (1),(2),(3),(4),(5),(6),(7),(8);
insert into seq select num+8 from seq;
insert into seq select num+16 from seq;
insert into seq select num+32 from seq;
insert into seq select num+64 from seq;
/* continue doubling the number of records until you feel you have enough */
For the task at hand it is not necessary to add many records, as you only need to make sure you never have more repetitions in your in condition than in the above seq table. I guess 128 will be good enough, but feel free to double the number of records a few times more.
Once you have the above, you can write queries like this:
select province_id,
name,
#pos := instr(#in2 := insert(#in2, #pos+1, 1, '#'),
concat(',',province_id,',')) ord
from (select #in := '0,1,2,3,1,0', #in2 := #in, #pos := 10000) init
inner join provinces
on find_in_set(province_id, #in)
inner join seq
on num <= length(replace(#in, concat(',',province_id,','),
concat(',+',province_id,',')))-length(#in)
order by ord asc
Output for the sample data and sample in list:
| province_id | name | ord |
|-------------|--------|-----|
| 1 | name 1 | 2 |
| 2 | name 2 | 4 |
| 3 | name 3 | 6 |
| 1 | name 1 | 8 |
SQL Fiddle
How it works
You need to put the list of values in the assignment to the variable #in. For it to work, every valid id must be wrapped between commas, so that is why there is a dummy zero at the start and the end.
By joining in the seq table the result set can grow. The number of records joined in from seq for a particular provinces record is equal to the number of occurrences of the corresponding province_id in the list #in.
There is no out-of-the-box function to count the number of such occurrences, so the expression at the right of num <= may look a bit complex. But it just adds a character for every match in #in and checks how much the length grows by that action. That growth is the number of occurrences.
In the select clause the position of the province_id in the #in list is returned and used to order the result set, so it corresponds to the order in the #in list. In fact, the position is taken with reference to #in2, which is a copy of #in, but is allowed to change:
While this #pos is being calculated, the number at the previous found #pos in #in2 is destroyed with a # character, so the same province_id cannot be found again at the same position.
Its unclear exactly what you are wanting, but here's why its not working the way you want. The IN keyword is shorthand for creating a statement like ....Where province_id = 1 OR province_id = 2 OR province_id = 3 OR province_id = 1. Since province_id = 1 is evaluated as true at the beginning of that statement, it doesn't matter that it is included again later, it is already true. This has no bearing on whether the result returns a duplicate.

MySQL: Select 3 most occuring strings either in column 1 or column 2

I'd like to have the 3 most occuring strings from 2 rows of my database. The thing is the string may occur in column1 or column2. I'd like to use only one query. Thanks in advance
Sample DB:
id string1 string2
1 foo bar
2 bar foo
3 api foo
Output should then be:
string count
foo 3
bar 2
api 1
You can execute the following query:
SELECT string, COUNT(*) FROM
(
SELECT string1 string FROM mytable
UNION ALL
SELECT string2 string FROM mytable
) sub
GROUP BY string
ORDER BY COUNT(*) DESC
LIMIT 3
where mytable is your table name.
With this query:
You take the union of all strings, either string1 or string2.
You group these string by their count.
You order them by the biggest count to the lowest.
You take only the three firsts.

Accessing column value of table A using value from table B

I've two tables say ABC and XYZ,
Table ABC:
B C ID ABC_ID
====================
50 30 10 2
60 31 11 3
Note: All the value fields are integers.
Table XYZ:
group condition value ID
================================
B = 50 10
C > 30 11
Note:
Column B and condition are varchar strings and value, ID columns are integers.
Using MySQL 5.5
I'm joining both the tables on the basis of column, ID.
There are many values for group in table XYZ and those values are columns in table ABC.
So, my questions are:
Once the ID matches, I will get the value of group as B in the above case from table XYZ. Then using the value, how should I get the value of B from table ABC?
I want to do something like :
select A.(X.group) from ABC A join XYZ X on A.ID = X.ID;
Once I'm able to get the value of column B using step 1 (as above), I need to form an expression like (group condition value) e.g. in able case B = 50 and replace the value of B from table ABC in the expression. The formed expression needs to be evaluated and if true, need to return the ABC_id from table ABC. How can I evaluate the expression?
I'm doing something like this:
select A.ABC_ID from XYZ X join ABC A on A.ID = X.ID where X.(A.group) A.condition A.value;
I've tried using PREPARE'ing and EXECUTE'ing but the join of ABC and XYZ would give multiple rows as a set. And it does not work.
SELECT X.group, X.condition, X.value
from XYZ X join ABC A
on X.ID = A.ID
into #colname, #condition, #value;
SET #qry = CONCAT('SELECT * from ABC WHERE ',#colname,#condition,#value);
PREPARE stmt FROM #qry;
EXECUTE stmt;
Thanks.
I created a sqlfiddle of this here: http://sqlfiddle.com/#!2/15e205/5
Note that I changed the names of group and condition because those are reserved words, and really aren't good choices for column names.
I'm using CONCAT() to build the query based on the values retrieved in XYZ.
SELECT grp, cndition, value
from XYZ
where id = 10
into #colname, #condition, #value;
SET #qry = CONCAT('SELECT * from abc WHERE ',#colname,#condition,#value);
PREPARE stmt FROM #qry;
EXECUTE stmt;

mysql select update

Got this:
Table a
ID RelatedBs
1 NULL
2 NULL
Table b
AID ID
1 1
1 2
1 3
2 4
2 5
2 6
Need Table a to have a comma separated list as given in table b. And then table b will become obsolete:
Table a
ID RelatedBs
1 1,2,3
2 4,5,6
This does not rund through all records, but just ad one 'b' to 'table a'
UPDATE a, b
SET relatedbs = CONCAT(relatedbs,',',b.id)
WHERE a.id = b.aid
UPDATE: Thanks, 3 correct answers (marked oldest as answer)! GROUP_CONCAT is the one to use. No need to insert commas between the ids using relatedids = CONCAT(relatedids,',',next_id) that is done automatic by GROUP_CONCAT.
You'll have to use the mysql group_concat function in order to achieve this: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
Look into GROUP_CONCAT(expr)
mysql> SELECT student_name,
-> GROUP_CONCAT(DISTINCT test_score
-> ORDER BY test_score DESC SEPARATOR " ")
-> FROM student
-> GROUP BY student_name;
You can't do that in standard SQL. You could write a stored procedure to do that. I had a similar problem, but I was using PostgreSQL so I was able to resolve it by writing a custom aggregate function so that you can do queries like
select aid, concat(id)
from b group by
aid
Update: MySQL has a group_concat aggregate function so you can do something like
SELECT id,GROUP_CONCAT(client_id) FROM services WHERE id = 3 GROUP BY id
as outlined here.