I'd like to add a column to a table whose value counts the number of times it is repeated on another table. Something like this:
Name NameID Quantity | NameID Franchisee Business BusinessID
John 12345 2 | 12345 CA Laundry 45678
Smith 45684 1 | 12345 CA Bakery 45679
| 45684 NY Shampoo 45680
The column Quantity is the one I want to add, I want it to count all the BusinessID that belong to his NameID: John has a NameId of 12345 and that NameID has 2 BusinessIDs assosiated to it.
I don't know how to do this, I want to add this value to an aspx project, maybe it'd be easier to make a function in c# to keep the DB as is and just show the values on the client.
In general you should not store that value. If you do, you'll have to update it every time you change the 2nd table, and then you'll have problems like what do I do if the update of the 2nd table succeeds, but that of the 1st table fails? (answer: use a transaction).
It is way simpler to calculate that value on the fly. You can do this in SQL:
SELECT
t1.Name, t1.NameID, COUNT(*) AS Quantity
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.NameID = t2.NameID
GROUP BY
t1.Name, t1.NameID
The only reason to store it would be if that value was an expensive calculation (in this case, it is not).
Related
I am trying to sort a table so that duplicates dont show up on it based on two different columns (MODEL_NUMBER and YEAR_INTRODUCED)
Right now my query is designed like:
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_" + decade + #"=#decade AND PRODUCT_LINE=#Line AND QUANTITY is not null AND QUANTITY <> 0 ORDER BY PRODUCT_NAME;";
Here is the table layout:
ARCHIVE_ID MODEL_NUMBER YEAR_INTRODUCED LOCATION
1001 B10 1989 SKID 43
1002 B10 1989 SKID 48
1003 B10 1989 SKID 73
The ARCHIVE_ID is the primary key. Should I use a group by? If I do use a group by which ARCHIVE_ID would stay?
Depends on the result set that you wish.
If the resultset only contains MODEL_NUMBER and YEAR_INTRODUCED, you can simply use distinct:
SELECT DISTINCT
MODEL_NUMBER,
YEAR_INTRODUCED
FROM ARCHIVE_DECADE_TBL
If you want the resultset to include other columns, you have to decide which values you want to show up. Since you only have one row per unique pairing, you can only show one value from the other columns. Which one do you want to show up? And do the values need to come from the same row?
You could do something like
SELECT MIN(ARCHIVE_ID),
MODEL_NUMBER,
YEAR_INTRODUCED,
MIN(LOCATION)
FROM ARCHIVE_DECADE_TBL
GROUP BY MODEL_NUMBER,
YEAR_INTRODUCED
...if you don't care if the values come from the same row.
If you do care, you have to do something a little more complicated, such as
SELECT A.*
FROM ARCHIVE_DECADE_TBL A
JOIN (SELECT MIN(ARCHIVE_ID),
MODEL_NUMBER,
YEAR_INTRODUCED
FROM ARCHIVE_DECADE_TBL
GROUP BY MODEL_NUMBER,
YEAR_INTRODUCED) B
ON A.ARCHIVE_ID = B.ARCHIVE_ID
May be the Question's title is not correctly defined what i actually wanted to ask. Here is the more specific description of my question
I have a following table User in my database which has a column i.e. Category which contains multiple values but separated by commas
S.no. Name Category
1 Ankit Ex Soldier, Senior Citizen
2 Ritu Widow, Senior Citizen
3 Akash Ex soldier
I wanted to search the record on the basis of category
for eg. If i search
select * from User where Category='Senior Citizen'
Then it must show Ankit and Ritu record.
How to do this.
plz help
try this:
select * from User where Category like '%Senior Citizen%'
You need LIKE operator:-
select * from User where Category LIKE '%Senior Citizen%'
select * from User where Category LIKE '%Senior Citizen%'
But you should use a separate table for Category.
Like Kiss László wrote you should separate the information in two tables. The professional term for this is called "Normalization". Most important to know are the 1NF, 2NF and 3NF (read this for detailed information).
So it should look like the following:
Table Persons
PersonId Name
1 Ankit
2 Ritu
3 Akash
Table Categories
CategoryId Name
1 Ex. Soldier
2 Senior Citizen
3 Widow
Table PersonCategories
PersonId CategoryId
1 1
1 2
2 2
2 3
3 3
Why should you do this?
In my opinion the biggest reason is performance. I made some test table with your current approach with a data set of 20k entries. The execution of the query took about ~200ms to return. With the schema above the following query executed in about ~1ms
SELECT
*
FROM
Persons AS p
JOIN
PersonCategories AS pc ON p.PersonId = pc.PersonId
JOIN
Categories AS c on pc.CategoryId = c.CategoryId
WHERE
c.Name = 'Senior Citizen'
Why is this query so much faster?
Because we can easily use indices on our columns. In the schema above the Persons.PersonId and Categories.CategoryId are the PRIMARY KEY columns of their tables. So to use them as a column for a JOIN operation has minimal costs. Both columns of the PersonCategories table are FOREIGN KEYS (ensures a valid database state and improves performance). Finally the Categories.Name column has an INDEX too.
Could this approach be bad?
In most cases this is the way to go. One reason not to do it this way, is if you have to handle lots of INSERTS. INSERTS in this schema have a much higher cost because all indices need to be updated after the INSERTS.
I have a question about how would I access the max value for gradterm within my SQL code? Here is an example of my plain code:
SELECT
Ceremony.Date, People.name, People.age
FROM
people
JOIN
Ceremony ON people.grad = Ceremony.grad
As you can see I am using the grad column of both tables to display the date of the Ceremony table based on what the grad is in the people table. Here is what I thought would work for getting the max grad values:
SELECT
Ceremony.Date, people.name, people.age
FROM
people
JOIN
Ceremony ON MAX(people.grad) = MAX(Ceremony.grad)
I get this error when I try to execute it:
An aggregate cannot appear in an ON clause unless it is in a subquery in a HAVING
clause or select list, and the column being aggregated in an outer reference.
I did try doing the Ceremony.Date with the MAX function, but that didn't work. Also here is an example of what the table looks like:
people table:
|name|age|gradterm|
-------------------
|jake|20 |A |
|joe |23 |B |
Ceremony table:
|Date |gradterm|
--------------------
|Dec 21 | A |
|Fall 21 | B |
When the gradterm in the people table "A" then the GridView I am using to display my SQL data (through a stored procedure) would display "Dec 21" as the Ceremony date. Also for gradterm in the peoples table to be "B", the gridview would display "Fall 21". All I am wanting it to get the max gradterm when comparing it to get the ceremony date. I thank everyone in advance for their help!
Basically, you need to group by the other fields before you can do aggregation
SELECT c.Date, People.name, People.age, c.GradTerm
FROM people
INNER JOIN (SELECT Date, MAX(grad) [GradTerm]
FROM Ceremony
GROUP BY Date) c
ON people.grad = c.grad
SELECT ID,Name FROM Master
id Name
1 John
2 John
3 Jack
4 Max
5 Jack
6 Max
7 Max
using above query i get all names repeated in dropdown.
i have to bind data in dropdown foreach Name there have
respective ID How can i do that.
I don't know the logic behind the data, but to get one name only once you have to filter out duplicate names and settle for one of the ids from the duplicate names.
SELECT MIN(id), Name
FROM Master
GROUP BY Name
The query above will output the occurence with the lowest id for each name, given that the id column is numeric.
The reason that your distinct query does not work, is that distinct filters on all columns in the result set, so in this case both name and id are used for uniqueness.
If you for some reason need all the ids for each name you have to filter on the ASP.NET side or look up the ids in the database once you know which person was selected.
Try this query it will return grouped as one
SELECT GROUP_CONCAT(ID), Name FROM your_tbl Group BY Name
Only place the Name column you will get the unique output. I think the problem is that the distinct keyword checks the primary key which is different per each row so it returns all the columns you only have to place the Name column. ( my understanding about distinct )
SELECT distinct Name FROM Master
output
Jack
John
Max
-- Below is what i tested
-- Created a table
Create table mytable(
ID bigint identity primary key,
UserName varchar(50)
)
-- Insert the records
INSERT INTO dbo.mytable(UserName) VALUES('John')
INSERT INTO dbo.mytable(UserName) VALUES('John')
INSERT INTO dbo.mytable(UserName) VALUES('Jack')
INSERT INTO dbo.mytable(UserName) VALUES('Max')
INSERT INTO dbo.mytable(UserName) VALUES('Jack')
INSERT INTO dbo.mytable(UserName) VALUES('John')
-- If i use below query
select distinct * from mytable
ID UserName
1 John
2 John
3 Jack
4 Max
5 Jack
6 John
-- and if i use this
select distinct UserName from mytable
output
Jack
John
Max
-- I think you should not allow the user to enter multiple users with the same name
-- what do you think about this
select UserName +' '+CAST(ID as varchar) as [Users] from mytable
John 1
John 2
Jack 3
Max 4
Jack 5
John 6
-- IN your code you can create a list<string,int> and stored in it. you can easily manage it in code
I have a datatable and it has 4 columns. My problem is some columns has same data, same date. I have to delete same data, same date. How can I delete dublicate data?
My Datatable:
In this table I have to delete 1 or 3 (Id) In code side with for or foreach loop. Because in the same date there is a same Isban.
Id Name Isban Date
1 A 123 09.09.2010
2 B 123 10.09.2010
3 C 123 09.09.2010
4 A 234 11.09.2010
5 B 342 12.09.2010
Thanks You
john
A standard way to do this is to run a select distinct query to insert the distinct records into a new table, delete the existing table, and then rename the new table to the previous table.
Edit: You can that you have to do this client-side.
One way is addressed here: Distinct in DataTable
Alternatively, loop through the table and store in a hash table each record; use the pair Isban/Date as the key and the record as the value. When you encounter a duplicate record it will already be in the hash table so you pass over it. Then, you can create a new data table from the records in the hash table.
If you DO have to do it in a loop, I would do it something like the following... Pre-query based on the minimum ID based on the given duplicate entitie elements, then delete for NOT being the minimum key
Select
FldDup1,
FldDup2,
min( IDKey ) as KeepThisID,
count(*) as TotalPerDupFields
from
YourTable
group by
FldDup1,
FldDup2
having
TotalPerDupFields > 1
In this case, you'll end up with a sample result of...
FldDup1 FldDup2 KeepThisID TotalPerDupFields
123 09.09.2010 1 2
as I was ignoring the 2nd column of "A", "B" and "C" as it didn't appear to be the indicator in your explanation of duplicates.
Then, I would isse a delete... via parameterized SQL-Delete query
Delete from YourTable
Where FldDup1 = ResultQuery.FldDup1
and FldDup2 = ResultQuery.FldDup2
and NOT IDKey = ResultQuery.KeepThisID