Join data from two tables with autoincrement id from two databases - c#

I would like to join data from tables from two databases. One is filed with predefined values (itemId, itemName) and other is filled by user (itemId, itemName, userId). Atributes itemId and itemName are the same, from first table we select all data, from second we select data by userId and combine these two results.
Joined data should be distinguish because ids are autoincrement and could be the same(doubled). We would like to fill drop down list with this data for example with datasource and dictionary (int is itemId, string is itemName) we could only have valueFiled and valueText in dropDownList but ids of these two tables could be the same and lather we don`t know from wich table is item selected by id.
Is there any elegant way to joint this, maybe with temp tables that we always when user is logged in join these two tables in temp table etc...
Thank you for your answers

I think you're looking for a union. Use a literal value to identify the source.
select 'predefined' as source, itemid, itemname
from predefined_values_table
union all
select 'user', itemid, itemname
from user_supplied_values_table
where userid = ?;
If you can accommodate only two columns, you might be able to use something like this instead. But you'll have to undo the string concatenation to get the id number.
select 'p:' || itemid, itemname
from predefined_values_table
union all
select 'u:' || itemid, itemname
from user_supplied_values_table
where userid = ?;

Related

Get some value based on the max date (query between two tables)

I have two tables, I would like to get one value based on some max date.
Here are the tables structures:
Items (ItemId, Name)
ItemData(ItemDataId, ItemFK, Invoice, EntryDate) - ItemFK is the foreign key of ItemId in Items table
What I know is the Name of the item only. I would like to get the latest Invoice based on the EntryDate (and the name).
I 1st need to get the itemid based on the name, then get the invoice based on the itemid but only the last one (so using max(enteydate).
How to do so with using innerjoin (or some other join sql query)?
You join to a derived table, which is a subquery with an alias.
select yourfields
from someTable join otherTablesMaybe on something
join (
select id, max(datefield) maxDate
from someTable
where whatever
group by id ) derivedTable on someTable.id = derivedTable.id
and someTable.datefield = maxDate
where whatever
The two where whatevers should be the same.

SQL statement having in which where clause have multiple values

I want to fill a ComboBox from database but I want two conditions of same column
table column Group contain four different values (rawmaterial, formula, packing , Chemical).
I want to select item names of group formula and packing
I am using the following query, but it's not working:
Select itemName from rawMaterial where Group = 'rawmaterial' , 'Packing'
Two alternatives:
Using OR:
Select itemName from rawMaterial where Group = 'rawmaterial' OR Group= 'Packing'
Using IN:
Select itemName from rawMaterial where Group IN ('rawmaterial' , 'Packing')

While Selecting based on ROWID - Distinct or Group By doesn't work in oracle

I have query like below , I tried to filter out duplicate columns by using Group BY
SELECT contacts.rowid AS ROW_PASS,
duty_rota.rowid AS ROW_PASS_ROTA,
duty_rota.duty_type AS DUTY_TYPE
FROM duty_rota,
duty_types,
contacts
WHERE duty_rota.duty_type = duty_types.duty_type
AND duty_rota.duty_officer = contacts.duty_id
AND sname IS NOT NULL
GROUP BY contacts.rowid,
duty_rota.rowid,
duty_rota.duty_type
ORDER BY duty_date
After playing with the query little bit I came to know we can't filter out distinct using group by while using ROWID. So can somebody please help me to write code (in SQL) with a logic that
if (any row is completely identical with another row of the query o/p)
{
then display only one column
}
I will be using the output as gridview's data source in C#, so if not in SQL - can you help me whether somehow in C# I can achieve to display only identical columns?
If you want to filter duplicate rows, you can use this query:
SELECT Max(duty_rota.rowid) AS ROW_PASS_ROTA,
duty_rota.duty_type AS DUTY_TYPE
FROM duty_rota,
duty_types,
contacts
WHERE duty_rota.duty_type = duty_types.duty_type
AND duty_rota.duty_officer = contacts.duty_id
AND sname IS NOT NULL
GROUP BY duty_rota.duty_type
ORDER BY DUTY_TYPE
Here you go: http://sqlfiddle.com/#!2/2a038/2
Take out the ROWID's. Example: If your table has 3 columns (colA, colB, colC) you could find exact row dups this way...
select a.* from
(
select count(*) dupCnt, colA, colB, colC from myTable
group by colA, colB, colC
) a
where dupCnt > 1
First, the ROWID is a unique field for each row, so using this field you will never have duplicates. The only solution here is to not use it. It's data does not hold anything you would want to display anyway.
Simply put, if you want no duplicates, you need the DISTINCT keyword:
SELECT DISTINCT field1,
field2
FROM table1,
table2
WHERE table1.key1 = table2.key1;
This will select all Field1, Field2 combinations from the two tables. Due to the DISTINCT keyword, each line will only be in the result list once. Duplicates will not be in the result list.
SELECT DISTINCT duty_rota.duty_type AS DUTY_TYPE
FROM duty_rota,
duty_types,
contacts
WHERE duty_rota.duty_type = duty_types.duty_type
AND duty_rota.duty_officer = contacts.duty_id
AND sname IS NOT NULL
ORDER BY duty_date
You will only need to GROUP BY if you need further operations on the result set, like counting the duplicates. If all you need is "no duplicates", the DISTINCT keyword is exactly what you are looking for.
Edit:
In case I misread your question and you want to see only those, that are duplicates, you need to group and you need to filter based on the groups criteria. You can do that using the HAVING clause. It's kind of an additional WHERE of the groups criteria:
SELECT FIELD1, FIELD2, COUNT(*)
FROM TABLE1, TABLE2
WHERE TABLE1.KEY1 = TABLE2.KEY1
GROUPB BY FIELD1, FIELD2
HAVING COUNT(*) > 1

Linq Query to Get Distinct Records from Two Tables

I have two Tables - tblExpenses and tblCategories as follows
tblExpenses
ID (PK),
Place,
DateSpent,
CategoryID (FK)
tblCategory
ID (PK),
Name
I tried various LINQ approaches to get all distinct records from the above two tables but not with much success. I tried using UNION and DISTINCT but it didnt work.
The above two tables are defined in my Model section of my project which in turn will create tables in SQLite. I need to retrieve all the distinct records from both the tables to display values in gridview.
Kindly provide me some inputs to accomplish this task. I did some research to find answer to this question but nothing seemed close to what I wanted. Excuse me if I duplicated this question.
Here is the UNION, DISTINCT approaches I tried:
DISTINCT # ==> Gives me Repetitive values
(from exp in db.Table<tblExpenses >()
from cat in db.Table<tblCategory>()
select new { exp.Id, exp.CategoryId, exp.DateSpent, exp.Expense, exp.Place, cat.Name }).Distinct();
UNION # ==> Got an error while using UNION
I think union already does the distict when you join the two tables you can try somethin like
var query=(from c in db.tblExpenses select c).Concat(from c in
db.tblCategory select c).Distinct().ToList();
You will always get DISTINCT records, since you are selecting the tblExpenses.ID too. (Unless there are multiple categories with the same ID. But that of course would be really, really bad design.)
Remember, when making a JOIN in LINQ, both field names and data types should be the same. Is the field tblExpenses.CategoryID a nullable field?
If so, try this JOIN:
db.Table<tblExpenses>()
.Join(db.Table<tblCategory>(),
exp => new { exp.CategoryId },
cat => new { CategoryId = (int?)cat.ID },
(exp, cat) => new {
exp.Id,
exp.CategoryId,
exp.DateSpent,
exp.Expense,
exp.Place,
cat.Name
})
.Select(j => new {
j.Id,
j.CategoryId,
j.DateSpent,
j.Expense,
j.Place,
j.Name
});
You can try this queries:
A SELECT DISTINCT query like this:
SELECT DISTINCT Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;
limits the results to unique values in the output field. The query results are not updateable.
or
A SELECT DISTINCTROW query like this:
SELECT DISTINCTROW Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;<br/><br/>
looks at the entire underlying tables, not just the output fields, to find unique rows.
reference:http://www.fmsinc.com/microsoftaccess/query/distinct_vs_distinctrow/unique_values_records.asp

Create an unique ID for multiple rows SQL

I have a number of user ID's. I am inserting these into a group table which will contain a column for the user's ID and the group ID. This will allow me to use the query "SELECT user_id FROM groups WHERE group_id = '3';" to retrieve user ID's of all the members of group 3.
My problem is that I currently have a list of all users IDs, which I got from a form, using the statements :
int i = 0;
String[] names = { Request.Form["usernames"]Split(' ') }; //retrieving names from form
List<int> user_ids = new List<int>();
foreach(string name in names){
int user_id = db.QueryValue("SELECT user_id FROM users WHERE username = name");
user_ids.Add(user_id); //now I have a list of all user_ids
}
I now wish to insert this data into the groups table, where all of the user_id values in the list will have the same group_ID. How can I do this?
//create a group from users
"INSERT INTO group (group_id, user_id) VALUES(?,?);
What you are talking about is a many-many relationship. You already have a users table:
**users**
userid
username
You need an additional table in the middle. The group table will just have something like:
**group***
groupid
groupName
You would then have a table in the middle. This table would look something like this:
**user_groups**
userid
groupid
You could still use your code to insert a user,
int i = 0;
String[] names = { Request.Form["usernames"]Split(' ') }; //retrieving names from form
List<int> user_ids = new List<int>();
foreach(string name in names){
int user_id = db.QueryValue("SELECT user_id FROM users WHERE username = name");
user_ids.Add(user_id); //now I have a list of all user_ids
}
After this, you would insert a group:
insert into group(groupName) values("Sample Group")
Then you could retrieve the group id and use that to insert into user_groups
select groupid from group where groupname="Sample Group"
insert into user_groups(userid,groupid) values(...
Also, the table structure should include primary keys and foreign keys (much like #sixlettervariables' answer)
In order to make this cleaner, you'll probably want to refactor your database setup slightly such that a third table relates users to groups:
users (user_id pk, ...)
groups (group_id pk, ...)
membership (user_id fk, group_id fk) unique(user_id, group_id)
When you needed to make a new group you simply insert into the groups table, obtain the group_id, and use that to populate the membership table for each of the users in that group.
You can use the select as the input to the insert
INSERT INTO group (group_id, user_id)
SELECT 1, user_id FROM users WHERE username in ("name1", name2")
You can join the names array back together with some commas.
You will need to iterate the user_ids list and do a separate insert statement for each user id.
You can insert all of the User ID's from one table into another using a sub-select and union statement as follows:
INSERT INTO group_table_name([user_id]) SELECT [user_id] FROM table_name
UNION ALL
By the way, you might want to change that table name since "group" is a keyword in SQL Server. Just a tip.
Insert Into GroupTable (GroupId, UserID) Select GroupID, USerID from UserTable group by GroupID, UserID)
This would work :)
Assuming you already know 3, you can do this without pulling the user ids into a local list and then inserting them individually (put in quotes specifically because the OP has their query in a similar string):
"INSERT dbo.group(group_id, user_id)
SELECT 3, user_id
FROM dbo.users
WHERE username = name;"
If you don't already know the group id, then please explain how you determined the group id should be 3.
EDIT based on further info.
CREATE TABLE dbo.Groups
(
GroupID INT IDENTITY(1,1) PRIMARY KEY,
GroupName NVARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE dbo.GroupUsers
(
GroupID INT NOT NULL FOREIGN KEY
REFERENCES dbo.Groups(GroupID),
UserID INT NOT NULL FOREIGN KEY
REFERENCES dbo.Users(UserID),
PRIMARY KEY(GroupID, UserID)
);
Now when you want to create a new group and add users to it:
DECLARE #GroupID INT;
INSERT dbo.Groups(GroupName) SELECT N'whatever (unique)';
SELECT #GroupID = SCOPE_IDENTITY();
Now you can loop through each user id:
INSERT dbo.GroupUsers(GroupID, UserID) SELECT #GroupID, <userid>;

Categories

Resources