i want to get all field but without same name in sql - sql

Hi I want to get all field
for example
select * from Stock where MemberId=3430
without same name value but I need Id
select distinct name,id,MemberId where MemberId=3430
Id is unique so distinct is not working correctly for me
Result is like
Id Name
1, Stock1
2, Stock2
3, Stock2
4, Stock1
It doesn't work because id is unique

You didn't specify the flavor of SQL that you're using. I've produced an answer for you that works in Postgres, SQL Server, and MySQL.
To be clear, my understanding of what you're looking for is the ability to return 1 record for "Stock2" with both of the id's associated with that value, rather than 2 separate records. To do this you need some sort of string aggregation capability. Here are three examples that will produce results you are looking for:
Postgres - dbfiddle link - https://www.db-fiddle.com/f/cWoFG13QYyi52Vww5HxoDi/1
SELECT array_agg(id), name
from sample
group by name;
SELECT array_to_string(array_agg(id), ','), name
from sample
group by name
MySQL
SELECT group_concat(id), name
from sample
group by name
SQL Server - sqlfiddle link - http://sqlfiddle.com/#!18/111ba7/4/0
SELECT string_agg(id, ','), name
from sample
group by name;

Related

duplicates to be removed sql

I have in database records
My sql:
SELECT
DISTINCT name, date(mod_wr)
FROM
test.object_stg
WHERE
ir = '4552724'
GROUP BY
name, date(mod_wr)
ORDER BY name
The last record is the same as the last but one. It has only a different date.
Is it possible to somehow query to return all records where there has been a change in the "name" column?
For record 4 and 5 there is the same name, only a different date. I would like it to return only a record of 4 and 5, because there was no change.
If you don't want to remove rows where values are resused. E.g. your line #2, you can use LAG() and then only include rows where the value is different to the previous. E.g.
select name, date(mod_wr) from
(
SELECT
name, mod_wr, lag(name) over(order by mod_wr) as prev_name
FROM
test.object_stg
WHERE
ir = '4552724'
)
WHERE prev_name IS NULL OR name <> prev_name
From your sample data, you have 3 distinct names. However, you cannot use distinct in your select statement because it applies to every field listed and none of the dates would provide an exact match.
However, you can use a group by statement in order to collate your titles together.
// MySQL 5.6 Statement
select name, date(mod_wr) from object_stg group by name;
// MSSQL 2017 Statement
select name, max(mod_wr) from object_stg group by name;
Both statements return 3 lines with just the BMW, 1.0 GL and 1.0 GLS showing with a single date.
SQL Fiddle

SQL select id=1

I've a table that has id_categoria field having comma separated value, e.g., 1,2,3,4,64,31,12,14, because a record can belong to multiple categories. If I want to select records that belongs to category 1, I have to run following SQL query
SELECT *
FROM cme_notizie
WHERE id_categoria LIKE '1%'
ORDER BY `id` ASC
and then select all records from the record set that have id_categoria exactly 1 in id_categoria. Let's assume that the value 1 does not exist, but column value like 12, 15, 120 ... still contains 1.
There is a way to take only 1? without taking derivatives or other?
As comments say, you probably shouldn't do that. Instead, you should have another table with one row per category. But if you decide to go with this inferior solution, you can do the following:
SELECT *
FROM cme_notizie
WHERE CONCAT(',', id_categoria, ',') LIKE '%,1,%'
ORDER BY id ASC

How to group SQL queries by only first few letters of a certain column's values?

I'm using Oracle sql developer. I have a table called data, one of the columns titled name. Earlier, I wanted to group items by name and get a total count, so I did this:
select count(*), name from data group by name;
Now, I want to group all the items whose names have first four letters in common. For example, I want to group all rows with name equal to Chris and all rows with name equal to Christine together. Is there an edit in the query above which will make it possible?
Just use the substr() function:
select substr(name, 1, 4) as name4, count(*)
from data
group by substr(name, 1, 4);
An alternate query which would fetch same results.
SELECT name4, COUNT (*)
FROM (SELECT SUBSTR (name, 1, 4) AS name4 FROM data)
GROUP BY name4;

Pick One Row per Unique ID from duplicate records

In Ms.Access 2010, I have a similar query table like one below where its displaying duplicate records. Problem is that even though I have unique ID's, one of the field has different data than other row since I have combined two seperate tables in this query. I just want to display one row per ID and eliminate other rows. It doesn't matter which row I pick. See below:
ID - NAME - FAVCOLOR
1242 - John - Blue
1242 - John - Red
1378 - Mary - Green
I want to just pick any of the the row with same ID. It doesn't matter which row I pick as long as I am displaying one row per ID is what matters.
ID - NAME - FAVCOLOR
1242 - John - Red
1378 - Mary - Green
Use the SQL from your current query as a subquery and then GROUP BY ID and NAME. You can retrieve the minimum FAVCOLOR since you want only one and don't care which.
SELECT sub.ID, sub.NAME, Min(sub.FAVCOLOR)
FROM
(
SELECT ID, [NAME], FAVCOLOR
FROM TABLE1
UNION ALL
SELECT ID, [NAME], FAVCOLOR
FROM TABLE2
) AS sub
GROUP BY sub.ID, sub.NAME;
Note NAME is a reserved word. Bracket that name or prefix it with the table name or alias to avoid confusing the db engine.
Try selecting union without the ALL parameter and see if you get the desired result.
Your new query would look like
"SELECT ID, NAME, FAVCOLOR FROM TABLE1; UNION SELECT ID, NAME, FAVCOLOR FROM TABLE2;"
If you just want the IDs, why is the color in the query? Maybe I'm missing something.
The only thing I could suggest is to use some aggregate function (min, max) to get one color.
Select
id,
name,
max(favcolor)
from (
(select * from table1) t1
union (select * from table2) t2 )t
group by
id,
name

Reporting against a CSV field in a SQL server 2005 DB

Ok so I am writing a report against a third party database which is in sql server 2005. For the most part its normalized except for one field in one table. They have a table of users (which includes groups.) This table has a UserID field (PK), a IsGroup field (bit) , a members field (text) this members field has a comma separated list of all the members of this group or (if not a group) a comma separated list of the groups this member belongs to.
The question is what is the best way to write a stored procedure that displays what users are in what groups? I have a function that parses out the ids into a table. So the best way I could come up with was to create a cursor that cycles through each group and parse out the userid, write them to a temp table (with the group id) and then select out from the temp table?
UserTable
Example:
ID|IsGroup|Name|Members
1|True|Admin|3
2|True|Power|3,4
3|False|Bob|1,3
4|False|Susan|2
5|True|Normal|6
6|False|Bill|5
I want my query to show:
GroupID|UserID
1|3
2|3
2|4
5|6
Hope that makes sense...
If you have (or could create) a separate table containing the groups you could join it with the users table and match them with the charindex function with comma padding of your data on both sides. I would test the performance of this method with some fairly extreme workloads before deploying. However, it does have the advantage of being self-contained and simple. Note that changing the example to use a cross-join with a where clause produces the exact same execution plan as this one.
Example with data:
SELECT *
FROM (SELECT 1 AS ID,
'1,2,3' AS MEMBERS
UNION
SELECT 2,
'2'
UNION
SELECT 3,
'3,1'
UNION
SELECT 4,
'2,1') USERS
LEFT JOIN (SELECT '1' AS MEMBER
UNION
SELECT '2'
UNION
SELECT '3'
UNION
SELECT '4') GROUPS
ON CHARINDEX(',' + GROUPS.MEMBER + ',',',' + USERS.MEMBERS + ',') > 0
Results:
id members group
1 1,2,3 1
1 1,2,3 2
1 1,2,3 3
2 2 2
3 3,1 1
3 3,1 3
4 2,1 1
4 2,1 2
Your technique will probably be the best method.