Join Tables MySQL - c#

I have multiple tables and made 2 sub-selects (UserRecord,CustomerRecord) that i would like to merge into 1 table
UserRecord
========================
| RecordID | UserName |
========================
| 1 | Sara |
| 1 | Tom |
| 2 | Sara |
| 2 | Kurt |
| 3 | Fre |
========================
Table: CustomerRecord
============================
| RecordID | CustomerName |
============================
| 1 | Jef |
| 2 | Alex |
| 2 | Peter |
============================
Table: This should be the result
=======================================
| RecordID | UserName | CustomerName |
=======================================
| 1 | Sara | - |
| 1 | Tom | - |
| 1 | - | Jef |
| 2 | Sara | - |
| 2 | Kurt | - |
| 2 | - | Alex |
| 2 | - | Peter |
| 3 | Fre | - |
=======================================
- = null
I tried with left, right, left outer, right outer ... join on the 2 tables but i don't get what i would like.
SELECT *
FROM UserRecord AS ur
INNER JOIN CustomerRecord AS cr ON ur.RecordID = cr.RecordID;

What you want is not a join, but a UNION:
SELECT RecordID, UserName, NULL AS CustomerName FROM UserRecord
UNION
SELECT RecordID, NULL AS UserName, CustomerName FROM CustomerRecord
... which just appends records from the two tables.
I'd just add that the order will not be the one you have shown in your expected result. If order is important then you should SELECT from this UNION and add an explicit ORDER BY clause on this outer select. Something like:
SELECT * FROM (
SELECT RecordID, UserName, NULL AS CustomerName FROM UserRecord
UNION
SELECT RecordID, NULL AS UserName, CustomerName FROM CustomerRecord
) ORDER BY RecordID, UserName, CustomerName

You can use a simple union
select recordid, username, null as customername from userrecord
union
select recordid, null, customername from customerrecord

Related

LINQ: equivalent for string_agg from PostgreSql

I need to concatenate multiple columns values to single value (separated with coma for example). I can do it by string_agg(u.name, ',') as Users in PostgreSql. I tried do it in linq query syntax but I failed - all time I just get list with split values instead of one row with values concatenated in one field.
Let's assume that I have only three tables:
Doc User Doc_User
+----+--------------------+ +----+-----------+ +----+-----------+
| Id | Path | | Id | Name | | DocId | UserId |
+----+--------------------+ +----+-----------+ +----+-----------+
| 1 | "C:\\Files\\A.txt" | | 1 | "Adam" | | 1 | 1 |
| 2 | "C:\\Files\\B.txt" | | 2 | "Benny" | | 1 | 2 |
| 3 | "C:\\Files\\C.txt" | | 3 | "Charlie" | | 2 | 1 |
+----+--------------------+ +----+-----------+ | 2 | 2 |
| 2 | 3 |
+-------+--------+
At the start I was trying simple join:
var model = (from d in db.Docs
join du in db.DU on d.Id equals du.DocId
join u in db.Users on du.UserId equals u.Id
select new DataModel() { DocPath = d.Path, UserName = u.Name }).ToList();
As I suspected I got list with separated rows:
C:\Files\A.txt | Adam
C:\Files\A.txt | Benny
C:\Files\B.txt | Adam
C:\Files\B.txt | Benny
C:\Files\B.txt | Charlie
But what I want to obtain is:
C:\Files\A.txt | Adam, Benny
C:\Files\B.txt | Adam, Benny, Charlie
string.Join() is not recognized by EF and I can't use it in linq queries, Aggregate() not working too. How can I achieve this?
I've prepared example for play with it: .Net Fiddle.
The code below groups the common documents by path using LINQ and then joins the grouped document's UserNames, using string.Join. I also think you don't need ToList() in this line select new DataModel() { DocPath = d.Path, UserName = u.Name }).ToList(); if you are going to use this solution because we are going to use LINQ again.
var grouped = model.GroupBy(x => x.DocPath);
foreach (var iGrouped in grouped){
string.Join(",",iGrouped.Select(x => x.UserName));
Console.WriteLine(iGrouped.Key + " | " + string.Join(",",iGrouped.Select(x => x.UserName)));
}

MSSQL Query omitting specific row value?

I have the following query to retrieve the customer sales report based on customer ID. It works, but how can I omit the customer name being duplicated?
select Cu.CustomerName, Cu.City, pd.pname,
Cs.qty, Cs.totalAmount, Cs.payed, Cs.credit, Cs.CreditEndDate
from Customer Cu
inner join CreditSales Cs on Cu.ID=Cs.CustomerID
left join Product pd on pd.pid=Cs.pid
where Cu.ID=6
order by Cu.CustomerName
The result is:
+--------+-------+---------------+----+----------+----------+----------+------------+
| Halima | Jimma | Mouse | 1 | 345.00 | 345.00 | 0.00 | 2015-08-29 |
| Halima | Jimma | Mobile | 10 | 92000.00 | 40000.00 | 52000.00 | 2015-08-23 |
| Halima | Jimma | Iphone | 2 | 13800.00 | 6500.00 | 7300.00 | 2015-08-28 |
| Halima | Jimma | Tape Recorder | 10 | 5175.00 | 4000.00 | 1175.00 | 2015-10-30 |
+--------+-------+---------------+----+----------+----------+----------+------------+
But I need like this:
+--------+-------+---------------+----+----------+----------+----------+------------+
| Halima | Jimma | Mouse | 1 | 345.00 | 345.00 | 0.00 | 2015-08-29 |
| | Jimma | Mobile | 10 | 92000.00 | 40000.00 | 52000.00 | 2015-08-23 |
| | Jimma | Iphone | 2 | 13800.00 | 6500.00 | 7300.00 | 2015-08-28 |
| | Jimma | Tape Recorder | 10 | 5175.00 | 4000.00 | 1175.00 | 2015-10-30 |
+--------+-------+---------------+----+----------+----------+----------+------------+
That means the customer name should displayed only one instance.
Any help? Thanks in Advance.
Based on Milen Pavlov response, you can try this:
SELECT CASE WHEN ROW_NUMBER() over (partition by [CustomerName] order by [CustomerName]) = 1 THEN [CustomerName] ELSE '' END
FROM Customer
ORDER BY [CustomerName]
This could do the job (I need you have to add an ordering in the over() clause):
select case when a.rn > 1 then '' else a.CustomerName end as CustomerName, a.City, a.pname, a.qty, a.totalAmount, a.payed, a.credit, a.CreditEndDate
from
(
select Cu.CustomerName, Cu.City, pd.pname,
Cs.qty, Cs.totalAmount, Cs.payed, Cs.credit, Cs.CreditEndDate, ROW_NUMBER() over (partition by Cu.CustomerName order by Cs.CreditEndDate) as rn
from Customer Cu
inner join CreditSales Cs on Cu.ID=Cs.CustomerID
left join Product pd on pd.pid=Cs.pid
where Cu.ID=6
) a
order by a.CustomerName
don't think it's a job for SQL but if you insists you can create two tables the first one with all the rows and columns and than delete the first row, and the other table with the first row and just make a left join and make the join on all the fields.

MySQL how many columns table have [duplicate]

This question already has answers here:
Find the number of columns in a table
(21 answers)
Closed 9 years ago.
I have table:
SHOW COLUMNS FROM `darbuotojai`;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| vardas | char(20) | YES | | NULL | |
| pavarde | char(30) | YES | | NULL | |
| email | char(100) | YES | | NULL | |
| pareigos | char(50) | YES | | NULL | |
| ilg_tel_nr | decimal(8,0) | NO | PRI | 0 | |
| trump_tel_nr | decimal(3,0) | NO | PRI | 0 | |
| inv_nr | char(10) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
How I can count columns in table with sql command?
And how I can identify them?
SELECT count(*)
FROM information_schema.columns
WHERE table_name = 'darbuotojai'
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = 'database_name'
AND table_name = 'tbl_name'
SELECT count(*) FROM information_schema.`COLUMNS` C
WHERE table_name = 'your_table_name'
AND TABLE_SCHEMA = "your_db_name"
TABLE_SCHEMA is required only if table name exists in more than one db

Gridview and Select query

I am working with gridview and tables, I am using c# and asp.net. Assuming I have 2 tables, lets just name it Profiles and Info.
In table profiles let's say I have fields with p_Id, FirstName, LastName and in Transaction I have I_Id, childsID, fathersID, mothersID.
This is what my tables looks like:
Profile
| p_Id | FirstName | LastName |
| 1 | Jack | Cole |
| 2 | Cynthia | Cole |
| 3 | Robert | Cole |
Info
| I_Id | childsID | fathersID | mothersID |
| 1 | 1 | 3 | 2 |
Now in my gridview I have to display FirstName, LastName, Father and Mother. But I need to display their names not their ID's.
For now my gridview looks like this:
First Name | Last Name | Father| Mother |
Jack | Cole | 3 | 2 |
what I want is like this:
First Name | Last Name | Father | Mother |
Jack | Cole | Robert Cole | Cynthia Cole |
try this
select p.firstName, p.LastName
, (select sp.FirstName+' '+sp.Lastname FROM profile sp WHERE sp.p_id=i.fathersid) as father
, (select sp.FirstName+' '+sp.Lastname FROM profile sp WHERE sp.p_id=i.mothersid) as mother
from info i
inner join profile p ON (p.p_id=i.childsID)

How to filter out similar rows (equal on certain columns) based on other column data

How would I select all rows distinct on Forename and Surname and where there's a duplicate select the one with the higher SomeDate, then Id if still duplicates e.g.
For:
| Id | Forename | Surname | SomeDate |
----------------------------------------
| 1 | Bill | Power | 2011-01-01 |
| 2 | James | Joyce | 2011-02-01 |
| 3 | Peter | Lennon | 2011-03-01 |
| 4 | John | Sellers | 2011-04-01 |
| 5 | James | Joyce | 2011-05-01 |
| 6 | Peter | Lennon | 2011-03-01 |
Results in:
| Id | Forename | Surname | SomeDate |
----------------------------------------
| 1 | Bill | Power | 2011-01-01 |
| 4 | John | Sellers | 2011-04-01 |
| 5 | James | Joyce | 2011-05-01 |
| 6 | Peter | Lennon | 2011-03-01 |
How could I achieve this in
T-SQL
From a DataTable using C#
Assuming SQL Server 2005+, use:
SELECT x.id,
x.forename,
x.surname,
x.somedate
FROM (SELECT t.id,
t.forename,
t.surname,
t.somedate,
ROW_NUMBER() OVER (PARTITION BY t.forename, t.surname
ORDER BY t.somedate DESC, t.id DESC) AS rank
FROM TABLE t_ x
WHERE x.rank = 1
A risky approach would be:
SELECT MAX(t.id) AS id,
t.forename,
t.surname,
MAX(t.somedate) AS somedate
FROM TABLE t
GROUP BY t.forename, t.surname
I'd tend to use subselects for the non-grouped values.
SELECT Forename, Surname,
(SELECT TOP 1 Id FROM myTable mt WHERE mt.Forename = m.Forename AND mt.Surname = m.Surname
ORDER BY m.SomeDate DESC) AS Id
(SELECT TOP 1 SomeDate FROM myTable mt WHERE mt.Forename = m.Forename AND mt.Surname = m.Surname
ORDER BY m.SomeDate DESC) AS SomeDate
FROM myTable m
GROUP BY Forename, Surname
Or you can filter it in the WHERE clause:
SELECT Id, Forename, Surname, SomeDate
FROM myTable m
WHERE m.Id = (SELECT TOP 1 Id FROM myTable mt WHERE mt.Forename = m.Forename AND mt.Surname = m.Surname
ORDER BY m.SomeDate DESC)
I'm afraid neither will be terribly efficient, but index toning will ameliate that if needed.
For a datatable example, you'd do essentially the same thing.
var recs = from record in dataTable
where record.Id ==
(from rec in dataTable
where rec.Forename == record.Forename && rec.Surname == record.Surname
orderby rec.SomeDate descending
select rec.Id).First()
select record;

Categories

Resources