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
Related
In my application, I fetch all tables in Database.
User will select table name and colum names to be masked.
Now i want to update sql table-columns with random generate string , which must be unique for each row without using primary key or unique key.
For example, In my Employeedb i have a table Employee.
Out of columns in Employee table, i want to mask data in name and city columns.
If table conatins 1000 rows, i want change name and city columns with 1000 unique values each. That means i want to update row by row.
Name Address City
Raghav flatno34 mumbai
Ranveer flatno23 chennai
This is orignal data
Name Adress City
Sbgha flatno34 mmjgujj
Lkhhvh flatno23 huughh
This is expected out
The table have primarykey sometimes.. There may be chances of not having primary key.
I have one more qn, I have this expected output in a datatable. Since i cannot predefine the table name and number of fields how will i write an update qry.
I think you will find my blog post entitled How to pre-populate a random strings pool very helpful for this requirement.
(Inspired by this SO answer from Martin Smith, to give credit where credit is due)
It describes an inline table valued user defined function that generates a table of random values, which you can use to update your data.
However, it does not guarantee uniqueness of these values. For that, you must use DISTINCT when selecting from it.
One problem you might encounter because of that is having a result with less values than you generated, but for 1,000 records per table as you wrote in the question it's probably not going to be a problem, since the function can generate up to 1,000,000 records each time you call it.
For the sake of completeness, I'll post the code here as well, but you should probably read the post at my blog.
Also, there's another version of this function in another blog post entitled A more controllable random string generator function for SQL Server - which gives you better control over the content of the random strings - i.e a string containing only numbers, or only lower digits.
The first thing you need to do is create a view that will generate a new guid for you, because this can't be done inside a user-defined function:
CREATE VIEW GuidGenerator
AS
SELECT Newid() As NewGuid
Then, the function code: (Note: this is the simpler version)
CREATE FUNCTION dbo.RandomStringGenerator
(
#Length int,
#Count int -- Note: up to 1,000,000 rows
)
RETURNS TABLE
AS
RETURN
-- An inline tally table with 1,000,000 rows
WITH E1(N) AS (SELECT N FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)) V(N)), -- 10
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --100
E3(N) AS (SELECT 1 FROM E2 a, E2 b), --10,000
Tally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY ##SPID) FROM E3 a, E2 b) --1,000,000
SELECT TOP(#Count) (
SELECT TOP (#Length) CHAR(
-- create a random number from a guid using the GuidGenerator view, mod 3.
CASE Abs(Checksum(NewGuid)) % 3
WHEN 0 THEN 65 + Abs(Checksum(NewGuid)) % 26 -- Random upper case letter
WHEN 1 THEN 97 + Abs(Checksum(NewGuid)) % 26 -- Random lower case letter
ELSE 48 + Abs(Checksum(NewGuid)) % 10 -- Random digit
END
)
FROM Tally As t0
CROSS JOIN GuidGenerator
WHERE t0.n != -t1.n -- Needed for the subquery to get re-evaluated for each row
FOR XML PATH('')
) As RandomString
FROM Tally As t1
Then, you can use it like this to get a distinct random string:
SELECT DISTINCT RandomString
FROM dbo.RandomStringGenerator(50, 5000);
I need to get an automatic method to link certain number consumptions with a payment.
I have for example in my first table.
Payments
ID Amount
1 $5,000
Then I have the following Table:
Consumptions
ID Amount CreatedDate
1 1000 2015-07-01 13:59
2 1000 2015-07-01 19:15
3 1000 2015-07-02 01:01
4 1500 2015-07-02 08:44
5 1000 2015-07-03 05:00
6 800 2015-07-03 19:57
7 200 2015-07-03 21:32
8 500 2015-07-03 23:48
I want to have a way that considering the $5000 payment amount, it automatically chooses the best combination of consumptions that make up the $5,000 sum.
If SQL is difficult, it can also be done on C#.
You will need a CTE that recursively joins with itself and checks all possible combinations.
with Anchor
(
Select Id, Amount, 0 as Level
From Consumptions
),
with RecursiveJoin
(
Select Id, Amount, Level From Anchor
Where Level = 0
UNION ALL
-- generate all possible permutations of amounts
Select c2.Id, c1.Amount + c2.Amount, Level + 1
From RecursiveJoin c1
Left Join RecursiveJoin c2 on c1.Id < c2.Id -- eliminate self joins and palindromes
)
Select *
From RecursiveJoin c
Join Payments p on c.Amount = p.Amount
I'm not completely confident that my recursion is correct. Hopefully that gets you started on the concept.
I'll leave it to you to add fields that concatenate lists of Id's of consumptions in each recursion.
It will give you multiple matches since multiple combinations of consumptions could match a payment. You could find the one with fewest combinations by keeping count in the recursion.
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).
I have a table as follows,
TypeID Name Date
-------------------------------
1 Carrot 1-1-2013
1 Beetroot 1-1-2013
1 Beans 1-1-2013
2 cabbage 1-1-2013
2 potato 1-1-2013
2 tomato 1-1-2013
2 onion 1-1-2013
If need 2 rows then it should return 2 rows from TypeId 1 and 2 rows from TypeId 2.If need the only 4 rows, means I have to get 4 rows from TypeId 1 and 4 rows from TypeId 2
but TypeId 1 has only 3 rows so we need to get only 3 rows for typeId 1
How to do that? Shall I add RowNumber?
For SQL Server;
EDIT: Your question changed slightly;
If you want want a maximum of x items per category, you can use ROW_NUMBER();
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY TypeID ORDER BY Name) rn FROM Table1
)
SELECT TypeID, Name, [Date] FROM cte
WHERE rn <=3 -- here is where your x goes
ORDER BY TypeID;
An SQLfiddle to test with.
You can write your query to order by the TypeID.
Then, if you're using SQL, you could use SELECT TOP N or LIMIT N (depending on the DB), or with TSQL and SQL Server, use TOP(N) to take the top N rows.
If you're using a LINQ based ORM from your C# code, then you can use Take(N), which automatically creates the appropriate query based on the provider details to limit the number of results.
I think you should use a query to select your 3 rows from type 1.....and then the however many rows from type 2 and then add the results together.
;With CTE(TypeID,Name,Date,RowNo)
AS
(
select *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) from TableVEG
)
Select Top(#noofRows*2) * from CTE where RowNo<=#noofRows order by rowno
The above query worked.. Thank u all... :-)
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