SQL string concatenation based on field value - c#

I am wondering if there is a straightforward way of concatenating a string based on the value of a field directly in SQL. I know it would be preferable to do in an application, but in this instance, I am only able to use SQL. For example, the following table:
Labels | Qty | LabelQty | OutputString
-------+-----+----------+--------------
1 | 30 | 30 | NULL
2 | 60 | 30 | NULL
2 | 120 | 60 | NULL
I would like to end up with the OutputString like so:
Labels | Qty | LabelQty | OutputString
-------+-----+----------+--------------
1 | 30 | 30 | 30|
2 | 60 | 30 | 30|30|
2 | 120 | 60 | 60|60|
I know this is very easy to do in C# or VB, but I am having a hard time thinking about how to accomplish this in straight SQL. Would I need to use a cursor and do each row one at a time? Unfortunately, I can't just use the string multiplier like in Ruby, such as:
SELECT (CONVERT(VARCHAR(10), LabelQty) + '|') * Labels
Any pointers are much appreciated.

You can use REPLICATE() function:
select replicate(cast(LabelQty as varchar(100)) + '|', Labels)
from mytable_1

You can try
SELECT REPLICATE(CONVERT(VARCHAR(10), LabelQty ) + '|',Labels )

While you haven't described how to produce output string, but I think that this can be done with case expression:
http://technet.microsoft.com/en-us/library/ms181765.aspx
And sample from that article:
SELECT ProductNumber, Name, "Price Range" =
CASE
WHEN ListPrice = 0 THEN 'Mfg item - not for resale'
WHEN ListPrice < 50 THEN 'Under $50'
WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
ELSE 'Over $1000'
END
FROM Production.Product
ORDER BY ProductNumber ;

Related

How to combine Duplicate data into single Data MySql

I was wondering if what is this called or is this even possible in MySql, or what should I do to achieve this. This is what Mysql Table Looks Like:
Desired Output:
you can use a query like this:
SELECT customerid
, CONCAT( SUM(CAST(item as INTEGER)), 'pcs,', SUBSTRING_INDEX(item, ',', -1) ) as item
FROM myitems
GROUP BY SUBSTRING_INDEX(item, ',', -1);
Sample
MariaDB [bernd]> SELECT * FROM myitems;
+----+------------+---------------+
| id | customerid | item |
+----+------------+---------------+
| 1 | 15 | 7pcs, Car |
| 2 | 15 | 2pcs, Car |
| 3 | 15 | 3pcs, Engine |
| 4 | 15 | 2pcs, Engine |
| 5 | 15 | 5pcs, Exhaust |
+----+------------+---------------+
5 rows in set (0.07 sec)
MariaDB [bernd]> SELECT customerid
-> , CONCAT( SUM(CAST(item as INTEGER)), 'pcs,', SUBSTRING_INDEX(item, ',', -1) ) as item
-> FROM myitems
-> GROUP BY SUBSTRING_INDEX(item, ',', -1);
+------------+---------------+
| customerid | item |
+------------+---------------+
| 15 | 9pcs, Car |
| 15 | 5pcs, Engine |
| 15 | 5pcs, Exhaust |
+------------+---------------+
3 rows in set, 5 warnings (0.02 sec)
MariaDB [bernd]>
Your table structures wont allow (anything near as easy). A better format of your table might be more like
id customerid item qty
1 15 Car 7
2 15 Car 2
3 15 Engine 3
4 15 Engine 2
5 15 Exhaust 5
Then, you could get what you are looking for easily such as
select
t.customerid,
t.item,
sum( t.qty )
from
YourTable t
group by
t.customerid,
t.item
This WOULD give your your
customerid item qty
15 Car 9
15 Engine 5
15 Exhaust 5
Having a properly formatted table vs trying to have a description requires parsing numeric values vs rest of description is never a good solution such as what you have here. Too many opportunities for bad answers.

Oracle Recursion

I want list all SOURCE_ID if the source has destination, the query below not work probably !!
select SOURCE_ID,
LINK_TYPE,
DESTINATION_ID
from LINK_TABLE
where link_table.link_type=1
and link_table.destination_is_deleted=0
START WITH link_table.source_id='100'
CONNECT BY PRIOR link_table.source_id=link_table.destination_id
Sample data
SOURCE_ID | DESTINATION_ID | LINK_TYPE| DESTINATION_IS_DELETED|
----------|-----------------|----------|-----------------------|
100 | 1500 | 1 | 0 |
100 | 1200 | 1 | 0 |
100 | 1300 | 1 | 1 |
1500 | 600 | 1 | 0 |
1500 | 700 | 1 | 0 |
700 | 88 | 1 | 0 |
Assuming you want to walk the hierarchy from the root nodes to the leaves this is what you need:
select SOURCE_ID,
LINK_TYPE,
DESTINATION_ID
from LINK_TABLE
where link_table.link_type=1
and link_table.destination_is_deleted=0
START WITH link_table.source_id='100'
CONNECT BY PRIOR link_table.destination_id = link_table.source_id
/
It's just a matter of swapping the referenced columns in the CONNECT BY PRIOR clause. Unfortunately the Oracle syntax is not intuitive here: I've been using it for over twenty years and I still have to test a query to make sure I've got them the right way round :)
I changed the query structure to solve the issue.
select SOURCE_ID,DESTINATION_ID,link_table.source_class,link_table.linktype,link_table.destination_class
from LINK_TABLE
where (link_table.source_id in( select link_table.DESTINATION_ID from link_table where link_table.source_id='100'and link_table.linktype=1 and link_table.destination_isdeleted=0 ))
and (link_table.linktype=1) or (link_table.source_id='100')

How can i get the sum of a database table to a variable?

I have a database table named Deposit and one of the column name in it is 30-12-2013. The column has two values such as 54,26.
i want to get the sum of that column column into a variable. I use the following code:
con.Open();
SqlCeCommand cmd11 = con.CreateCommand();
cmd11.CommandText = "select sum(30-12-2013) from Deposit";
int result = ((int)cmd11.ExecuteScalar());
displaylabel.Text = result.ToString();
con.Close();
But, I am getting the value of variable 'result' as -3990.
Whats wrong with my code.. Please help me.. Thanks in advance..
(30-12-2013) * 2 (because you have two entries) = -1995 * 2 = -3990
You have to use:
SELECT sum([30-12-2013])
FROM dbo.Deposit
This has already been answered so instead of answering your actual question I am going to propose an alternative solution.
Instead of having a table as follows:
SomeColumn | 30-12-2013 | 31-12-2013 | 01-01-2014
-----------+------------+------------+------------
A | 540 | 100 | 246
B | 130 | 90 | 377
Have a normalised table:
SomeColumn | Date | Amount
-----------+------------+--------
A | 2013-12-30 | 540
A | 2013-12-31 | 100
A | 2014-01-01 | 246
B | 2013-12-30 | 130
B | 2013-12-31 | 90
B | 2014-01-01 | 377
This means you don't require a new column for every day. So your query would become:
SELECT SUM(Amount) AS Amount
FROM Deposit
WHERE Date = '20131230';
And if you wanted to reproduce your original structure you can use:
SELECT SomeColumn,
SUM(CASE WHEN Date = '20131230' THEN Amount ELSE 0 END) AS [30-12-2013],
SUM(CASE WHEN Date = '20131231' THEN Amount ELSE 0 END) AS [31-12-2013],
SUM(CASE WHEN Date = '20140101' THEN Amount ELSE 0 END) AS [01-01-2014]
FROM Deposit
GROUP BY SomeColumn;
Example on SQL Fiddle (Using SQL Server as it doesn't support SQL Server CE)
Try to use brackets for columns with unusual names -
cmd11.CommandText = "SELECT SUM([30-12-2013]) FROM Deposit";

how to dynamically create multiple select statement and store it in a datatable

the case here is the number of columns i would like to store to the datatable depends on the number of available data. i would need a multiple select statements to collect all the data.
select test_result.stud_id,test_info.max_score,
test_result.test_score
from test_result left join test_info
on test_result.test_info_id = test_info.test_info_id
where test_info.test_type_id = 1 and test_info.test_num = 1;
i would have to repeat this code over and over again until the test_num reaches the current maximum count. i was thinking of looping this code while storing it to the datatable.this is what i would like the datagridview would display.
|Quiz Number | Quiz#1 | Quiz #2 | Quiz #3 | Quiz #4 | Quiz #5 |
|Max score | 20 | 25 | 30 | 15 | 15 |
|student 1 | 18 | 22 | 25 | 12 | 14 |
|student 2 | 19 | 20 | 25 | 11 | 13 |
|student 3 | 20 | 24 | 20 | 12 | 11 |
the display of data would be in rows. so each row would require a different select statement in order to display the required data.
Something like below will woek for you
select
test_result.stud_id,
max(case when test_result.test_info_id =1 then test_result.test_score end) as quiz_1,
max(case when test_result.test_info_id =2 then test_result.test_score end) as quiz_2,
max(case when test_result.test_info_id =3 then test_result.test_score end) as quiz_3,
.
.
.
from test_result left join test_info
on test_result.test_info_id = test_info.test_info_id
where test_info.test_type_id = 1 and test_info.test_num = 1
group by test_result.stud_id;

MySQL Select query - Sorting data based on date

I'm using MySQL.
This is table name item_supplier
supplier_ID Item_ID Date Price QTY
1 1 2012-01-01 00:00:00 500.00 2
1 1 2012-01-03 00:00:00 450.00 10
2 1 2012-01-01 00:00:00 400.00 5
3 1 2012-05-01 00:00:00 500.00 1
I need a select query showing a table something like this.
supplier_ID 2012-01-01 2012-01-03 2012-05-01
1 500.00(2) 450.00(10) null
2 400.00(5) null null
3 null null 500.00(1)
or, at least,
supplier_ID 2012-01-01 2012-01-03 2012-05-01
1 500.00 450.00 null
2 400.00 null null
3 null null 500.00
I hope someone can help me on this or give me a hint.
If there aren't a finite number of dates that are known beforehand, then you can't do what you want in MySQL alone.
Your best bet is to get a table like:
+---------+------------+-------------+-------------+
| Item_ID | Date | supplier_ID | price |
+---------+------------+-------------+-------------+
| 1 | 2012-01-01 | 1 | 500.00 (2) |
| 1 | 2012-01-01 | 2 | 400.00 (5) |
| 1 | 2012-01-03 | 1 | 450.00 (10) |
| 1 | 2012-05-01 | 3 | 500.00 (1) |
| ... | ... | ... | ..... |
Which can be done with:
SELECT Item_ID,Date,supplier_ID,CONCAT(FORMAT(Price,2),' (',QTY,')') AS price
FROM item_supplier
ORDER BY Item_ID,Date,supplier_ID;
Then on the C# side, loop through the results and print your desired output.
Since the output is now sorted by Item_ID, Date, and then supplier_ID, it's simple to loop through the results and then output in the format you want.
First of My SQL does not support to Crosstab/Pivot Query. So you need to create Dynamic temp Table for Columns and then inset record into it.
Like, First you have to fetch all date in one cursor and then create temp table and insert columns based on date's Cursor . After Creating table create another cursor for inserting rows. and fetch every row and update temp table.I have also done this using this way....
If you have any query please contact.

Categories

Resources