concatenate rows for many conditions - tsql

I need to concatenate the rows(taille). for example, for the code_commande 001 and code_article=1, I need to concatenate in list all taille which have these two conditions. another example, for code_commande=001 and code_article=2, the same job I need to concatenate in a list all taille which have these two conditions. this for all
code_commande code_article taille
001 1 s
001 1 m
001 1 xl
001 1 x52
001 2 m
001 1 5566
001 2 x52
001 1 xl
002 1 s
002 2 m
001 3 xxl
002 3 xs
001 1 ml
001 1 xs32
I need to concatenate taille for each code_commande for each code_article
example of result:
001 1 s,m,xl etcc
dynamically
I should have a table who grouped the ( taille) for each code_commande for each code_article like:
001 1 s,m,xl,
001 2 s,xl,l
002 1 xs,ettcc
I have tried this query but ,it concatenate all (taille) for all rows
the query
Select [code_commande],[code_article], SUBSTRING(
(
SELECT ',' +[taille] AS 'data()'
FROM [dbo].[commande] FOR XML PATH('')
), 2 , 9999) As taille_commande
from [dbo].[commande]
order by [code_article],[code_commande]desc

As mentioned, STRING_AGG() is your friend for this requirement. Assuming your original post contained the schema you're working with, a simple aggregate query will give you the results you want.
select code_commande, code_article, STRING_AGG(taille, ',') as taille_commande
from dbo.commande
group by code_commande, code_article
STRING_AGG reference
Note this is only available in SQL Server 2017+ and azure. To see a possible solution for previous versions, see this duplicate.

Related

Count users with more than X amount of transactions within Y days by date

Scenario: Trying to count more active users for time series analysis.
Need: With postgreSQL(redshift) Count customers that have more than X unique transactions within Y days from said date, group by date.
How do i achieve this?
Table: orders
date
user_id
product_id
transaction_id
2022-01-01
001
003
001
2022-01-02
002
001
002
2022-03-01
003
001
003
2022-03-01
003
002
003
...
...
...
...
Outcome:
date
active_customers
2022-01-01
10
2022-01-02
12
2022-01-03
9
2022-01-04
13
You may be able to use the window functions LEAD() and LAG() here but this solution may also work for you.
WITH data AS
(
SELECT o.date
, o.user_id
, COUNT(o.trans_id) tcount
FROM orders o
WHERE o.date BETWEEN o.date - '30 DAYS'::INTERVAL AND o.date -- Y days from given date
GROUP BY o.date, o.user_id
), user_transaction_count AS
(
SELECT d.date
, COUNT(d.user_id) FILTER (WHERE d.tcount > 1) -- X number of transactions
OVER (PARTITION BY d.user_id) user_count
FROM data d
)
SELECT u.date
, SUM(u.user_count) active_customers
FROM user_transaction_count u
GROUP BY u.date
ORDER BY u.date
;
Here is a DBFiddle that demos a couple options.

How to you CASE for IF THEN issue?

I am trying to select rows that fall under these conditions
IF kid=IND and kid=Family
then select Kid=IND
If kid only has Family
then select family.
if kid only has IND
then select IND.
How would I go about doing this using CASE?
ex.
kid_id date type
001 1/1/2013 IND
001 1/1/2013 Family
002 1/2/2013 Family
003 1/3/2013 IND
Results
001 1/1/2013 IND
002 1/2/2013 Family
003 1/3/2013 IND
select
case
When (kid=ind and kid=family) Then ind
When kid=family then family
When kid=ind then ind
else
null
end
From SomeTable
given kid, ind and family are columns in the table.
Do you mean something like this
select kid_id,date,
case
When (kid=ind and kid=family) Then 'Both'
When kid=family then family
When kid=ind then ind
else
'None'
end as TypeGroup
From SomeTable

Partitioning Related Rows into Groups

I have some legacy product data that has proven difficult to work with. The products can be sold with 1, 2 or 3 parts, and the way the system was designed, parts 2 and 3 for an ordered product were simply subsequent rows after the first row for that product.
Here is some sample data....
----------------------------------------------------------
OrderId Sku Type Row_Id OtherColumns...
----------------------------------------------------------
123 001 Double 0 Other stuff..
123 001 Double 1 Other stuff..
123 001 Double 2 Other stuff..
123 001 Double 3 Other stuff..
123 002 Single 4 Other stuff..
123 003 Triple 5 Other stuff..
123 003 Triple 6 Other stuff..
123 003 Triple 7 Other stuff..
123 001 Double 8 Other stuff..
123 001 Double 9 Other stuff..
123 002 Single 10 Other stuff..
123 002 Single 11 Other stuff..
123 002 Single 12 Other stuff..
123 002 Single 13 Other stuff..
The old software (VB) deals with this by iterating over the rows and looking forward as it loops, getting the information it needs from the rows, and then skips them.
Fast forward 8 years...I have inherited this system in my new job and have rewritten the system from the ground up. The problem I'm having is getting that legacy data into my new format.
I'm looking for a way to select the same data, and partition it by the appropriate segment numbers. I've used RANK() OVER(PARTITION BY) with no success. I think I'm just not doing it right.
Ideally, I'd like to be able to generate a result set that looks like this: (NOTE the Segment column)
-------------------------------------------------------------------
OrderId Sku Type Row_Id Segment OtherColumns...
-------------------------------------------------------------------
123 001 Double 0 1 Other stuff..
123 001 Double 1 2 Other stuff..
123 001 Double 2 1 Other stuff..
123 001 Double 3 2 Other stuff..
123 002 Single 4 1 Other stuff..
123 003 Triple 5 1 Other stuff..
123 003 Triple 6 2 Other stuff..
123 003 Triple 7 3 Other stuff..
123 001 Double 8 1 Other stuff..
123 001 Double 9 2 Other stuff..
123 002 Single 10 1 Other stuff..
123 002 Single 11 1 Other stuff..
123 002 Single 12 1 Other stuff..
123 002 Single 13 1 Other stuff..
Ideally, I'd like to avoid cursors or loops. I'll be using the query to migrate millions of records that are derived from multiple tables.
Thanks in advance for your help.
EDIT
I've updated the sample data to show that I do indeed have back to back groups that I need to isolate.
select OrderId,
Sku,
Type,
Row_Id,
(row_number() over(partition by Type order by Row_Id) - 1) %
case Type
when 'Single' then 1
when 'Double' then 2
when 'Triple' then 3
end + 1
from YourTable
order by Row_Id
SQL Fiddle

How to sum of the specified column value

Using Crystal Report 7
ID Value
001 100
002 200
003 400
004 500
...
I have n number of row, from that i want to sum of value from 003 to n, i don't want to sum of 001 and 002.
In a report footer, i need to add sum of value from 003 to n.
How to create a formula for the above condition, Need formula help
You can use the same solution as: How to add rows at runtime
Create a new formula field: if {table.id} in ['001', '002'] then 1 else 2;
Create a group using this formula
Suppress the group header
Add your total fields to the group footer (you will get a total of 001 + 002 then a total of 003... n

How to arrange the rows in a specific order

Using Crystal Report 7
ID Name
001 Raja
002 Vijay
003 Suresh
004 Mahes
005 Salma
I want to arrange by id (003, 001, 004, 002, 005)
Expected output
ID Name
003 Suresh
001 Raja
004 Mahes
002 Vijay
005 Salma
Note: Maximum row is 5 only, it will not exceed more than 5.
I need to add 5 group or any other method is there for arranging the rows.
Need Crystal report formula or suggestion help
In later versions of crystal you can set a custom sort order but if this feature isn't available in CR7 you should be able to create a formula:
if {table.id} = '003' then
1
else if {table.id} = '001' then
2
else if {table.id} = '004' then
3
else if {table.id} = '002' then
4
else if {table.id} = '005' then
5
else
999;
Then sort on that formula.