Find missing element SQL - sql

I have a couple of tables of a database where one defines a set of matrices and the other the data in the matrices
Matrices
Id Name
1 M1
2 M2
3 M3
4 M4
MatrixElements
Matrix_Id ElementKey Value
1 1 234
1 2 234
1 3 4432
2 1 234
2 2 13
2 3 123
3 1 34
3 3 345
4 1 234
4 2 11
4 3 344
So the Matrix_Id column is a foreign key back to the Id of the Matrices table. The ElementKey reprents an ij pair. The matrices are sparse, so there may or may not be an element with a specific key. However, if one matrix has a particular ElementKey, then the ElementKey with that ID must be defined in ALL matrices.
Is there some SQL that I can run that will find Matrix_Id and ElementKey combinations for any offending entries, i.e. one that is not defined for all matrices? So for the example above, ElementKey = 2 is defined for Matrix 1, 2 and 4 but not 3, so I would expect [Matrix = 3, ElementKey = 2] back.

This will get the missing elements and the matrices they are in:
select m.id, me.element_key
from matrices m cross join
(select distinct element_key from matrix_elements me) e left join
matrix_elements me
on me.matrix_id = m.id and me.element_key = e.element_key
where me.matrix_id is null;
The cross join generates all combinations of matrices with known element keys. The left join and where then find the ones that are missing.

First we make a list of all live elements, then cross join to all active matrices. With this list, we left join the active elements and use a case to determine if they exist.
I've used ANSI, but a CTE would be better if SQL server or Oracle.
select c.id, c.ElementKey, case when b.MatrixID is null then 0 else 1 end as InPlace
from
(
select id, a.ElementKey
from Matrices
cross join
(
select distinct ElementKey
from MatrixElements
) a
) c
left join Matrices b
on b.Matrix_id = c.id
and b.ElementKey = c.ElementKey

Thanks to the responses I have had. I haven't been able to implement it effectively because I am using Entity Framework and it is hard to translate the code given to a query statement that will give me back the results. I did take inspiration from the samples given and this is what I came up with.
public class Matrix
{
[Key]
public int Id { get; set; }
public virtual List<MatrixElement> Data { get; set; }
}
public class MatrixElement
{
[Key]
public int Id { get; set; }
public int OdPairKey { get; set; }
public double Value { get; set; }
}
public class EngineDataContext : DbContext
{
public virtual DbSet<Matrix> MatrixFiles { get; set; }
public virtual DbSet<MatrixElement> MatrixData { get; set; }
}
public class SqliteRepository
{
private readonly EngineDataContext _dataContext;
public SqliteRepository(EngineDataContext dataContext)
{
_dataContext = dataContext;
}
public IEnumerable<Tuple<Matrix, int>> FindMissingODPairs(IEnumerable<Matrix> matrices)
{
IEnumerable<Matrix> matricesWithData =
matrices.Select(m => _dataContext.MatrixFiles
.Include("Data").First(mf => mf.Id == m.Id));
// Do the cross join on matrices and OD pairs
IEnumerable<dynamic> combinations =
from m in matrices
from od in matricesWithData.SelectMany(mat => mat.Data.Select(md => md.OdPairKey)).Distinct()
select new { M = m.Id, O = od };
// Find all the used matrix / OD pair combinations
IEnumerable<dynamic> used =
from m in matricesWithData
from od in m.Data
select new { M = m.Id, O = od.OdPairKey };
// Find the missing combinations with a simple "Except" query
return combinations
.Except(used)
.Select(c => new Tuple<Matrix, int>(matrices.First(m => m.Id == c.M), c.O));
}
}

Related

Ef core search on child , order on parent

I have two model Parent and Child and I want to retrieve all Distinct parent that has unitid = 5 and order by family
public class Parent
{
public int Id { get; set; }
public string Family { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public int UnitId { get; set; }
public Parent parent { get; set; }
}
parent table has 500000 record and child table has 2000000 record . I use SelectMany And Distinct but it take 8s to retrieve records
var parents= Context.Set<Parent>()
.SelectMany(x => x.Children.DefaultIfEmpty(),
(u, r) => new {
Parent = u,
Child = r })
.Where(x=>x.Child.UnitId == 5)
.Select(m => new Parent{
Id = m.Parent.Id,
Family= m.Parent.Family
})
.Distinct()
.OrderBy(x=>x.Family)
.Take(30).Skip(0).ToList();
Tranlate to :
SELECT [t].[Id], [t].[Family] FROM (
SELECT distinct [a].[Id], [a].[Family]
FROM [Parent] AS [a]
LEFT JOIN [Children] AS [r] ON [a].[Id] = [r].[ParentId]
WHERE ([r].[unitid] = 5) AS [t] ORDER BY [t].[family] OFFSET 0 ROWS FETCH next 30 ROWS ONLY
Or
var parents = Context.Set<Children>()
.Include(x=>x.Parent)
.Where(x=>x.UnitId ==5)
.Select(m => new Parent{
Id = m.ParentId ,
Family = m.Parent.Family})
.Distinct()
.OrderBy(x=>x.Family)
.Take(30).Skip(0).ToList();
Translatr to :
SELECT [t0].[Id],[t0].[Family] FROM ( SELECT DISTINCT [t].[Id], [t].[Family]
FROM [Children] AS [r]
INNER JOIN (
SELECT [a].[Id] , [a].[Family]
FROM [Parent] AS [a]
) AS [t] ON [r].[ParentId] = [t].[Id]
WHERE ([r].[UnitId] = 5) AS [t0] ORDER BY [t0].[Family] OFFSET 0 ROWS FETCH next 30 ROWS ONLY
1 . When use order by id it is very fast
2 . when use order by family and take,skip it is slow
3 . family is indexed
4 . Ef Core 3.1
Which solution is Correct or better ?
Check these two queries for performance:
var parents =
from p in Context.Set<Parent>()
where p.Children.Any(c => c.UnitId == 5)
orderby p.Family
select p;
parents = parents
.Take(30)
.Skip(0)
.ToList();
And another one:
var parentIds =
from c in Context.Set<Child>()
where c.UnitId == 5
select c.ParentId
var parents =
from p in Context.Set<Parent>()
join id in parentIds.Distinct() on p.Id equals id
orderby p.Family
select p;
parents = parents
.Take(30)
.Skip(0)
.ToList();

Understanding MVC SQL query. From, where, then select

I inherited the code below and was hoping someone could explain it to me. The model definition is fine, but I am not understanding the string Minor1 setup. The SQL query looks backwards. Is this a normal practice? I tried putting the query in the normal order (select, from, where) and it did not work.
Example for model:
[Table("MINORS")]
public class VerifyDataModel_MINORS
{
[Key]
public string MINORS_ID { get; set; }
public string MINORS_DESC { get; set; }
}
string Minor1 = (from A in db.VerifyDataModel_STUDENT_PROGRAM
join B in db.VerifyDataModel_STPR_STATUS on A.STUDENT_PROGRAMS_ID equals B.STUDENT_PROGRAMS_ID into AB
from AB1 in AB.Where(B => B.POS == 1).DefaultIfEmpty()
join C in db.VerifyDataModel_STPR_MINOR_LISTS on A.STUDENT_PROGRAMS_ID equals C.STUDENT_PROGRAMS_ID into ABC
from ABC1 in ABC.Where(C => C.STPR_MINORS.Substring(0, 2) != "XX").DefaultIfEmpty()
join D in db.VerifyDataModel_MINOR on ABC1.STPR_MINORS equals D.MINORS_ID into ABCD
from ABCD1 in ABCD.DefaultIfEmpty()
where AB1.STPR_STATUS == "A"
where ABC1.STUDENT_PROGRAMS_ID.Substring(8, 5) != "GENED"
where A.STUDENT_PROGRAMS_ID.Substring(0, 7) == personId
where ABC1.STPR_MINOR_END_DATE == null
select ABCD1.MINORS_DESC).Min();

how to compare string linq with sub query with another linq with sub query

I Have 4 tables:
Position Table:
| Position | PositionId |
| driver | 1 |
| clerk | 2 |
position Skill table:
| SkillId | skill | PositionId |
| 1 | driving | 1 |
| 2 | drifting | 1 |
Worker table:
| Name | WorkerId |
| John | 1 |
| alex | 2 |
Worker skill table:
| skillId | skill | WorkerId |
| 1 | driving | 1 |
| 2 | drifting | 1 |
I join the position table with position Skill table
and worker table with worker skill
What I'm having trouble with is how can I compare the two joined tables to have a result of
for example:
I need to know who's worker have all the specific skills that the position have
Like:
I Select position with positionId of 1 and have the skillname of driving and drifting
I need to get the Worker with the same skills with driving and drifting also
so far i got this:
var PositionsWithSkills = (from a in db.Client_Customer_Position
where a.ID == position
select new
{
PositionID = a.ID,
RequiredSkills = (from b in db.Client_Customer_Position_Skills
where b.ClientCusPosId == a.ID
select b.SkillName)
}).ToList();
var WorkersWithSkills = (from x in db.Workers
select new
{
workerId = x.ID,
Skills = (from y in db.Worker_Skills
where y.Worker_ID == x.ID
select y.SkillName)
}).ToList();
var PositionWithSkilledWorkers = (from pos in PositionsWithSkills
select new
{
PositionId = pos.PositionID,
Workers = (from worker in WorkersWithSkills
where pos.RequiredSkills.All(skill => worker.Skills.Any(workerSkill => workerSkill == skill))
select worker.workerId)
}).ToList();
the two query works well.. but the last query where i must compare the two query =.. i cant get the worker id
and can i turn this to a stored proc?
Sorry if am wrong. What I got to know from your question is you want the workers list satisfying all the skills of the position you pass. If this is what you want you may try this:
var workerWithallSkill = (from u in db.workerList join x in db.workerSkillList on u.WorkerId equals x.WorkerId
where ((from y in db.workerSkillList where y.WorkerId == u.WorkerId select y).Count() == (from p in db.positionSkillList where p.PositionId == 1("pass your positionId here") select p).Count())
select u).ToList().Distinct();
or if you want to use lambda expression you can use this
var workerWithallSkill = (from u in workerList join x in workerSkillList on u.WorkerId equals x.WorkerId where (workerSkillList.Where(y=> y.WorkerId == u.WorkerId).Count() == positionSkillList.Where(p=>p.PositionId == 1).Count()) select u).ToList().Distinct();
For more understanding you can try the below code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
IList<Position> positionList = new List<Position>() {
new Position(){ position="Driver", PositionId=1}
,new Position(){ position="clerk", PositionId=2}
};
IList<PositionSkill> positionSkillList = new List<PositionSkill>() {
new PositionSkill(){ Skill = "driving",skillid = 1,PositionId = 1}
,new PositionSkill(){ Skill = "drifting",skillid = 2,PositionId = 1}
};
IList<Worker> workerList = new List<Worker>() {
new Worker(){ name = "John",WorkerId = 1}
,new Worker(){ name = "alex",WorkerId = 2}
};
IList<WorkerSkill> workerSkillList = new List<WorkerSkill>(){
new WorkerSkill(){Skill = "driving",skillid = 1,WorkerId = 2}
, new WorkerSkill(){Skill = "drifting",skillid = 2,WorkerId = 2}
};
var workerWithallSkill = (from u in workerList join x in workerSkillList on u.WorkerId equals x.WorkerId where (workerSkillList.Where(y => y.WorkerId == u.WorkerId).Count() == positionSkillList.Where(p => p.PositionId == 1).Count()) select u).ToList().Distinct();
foreach (var worker in workerWithallSkill)
{
Console.WriteLine(worker.name);
}
Console.ReadLine();
}
}
public class Position
{
public string position { get; set; }
public int PositionId { get; set; }
}
public class PositionSkill
{
public int skillid { get; set; }
public string Skill { get; set; }
public int PositionId { get; set; }
}
public class Worker
{
public string name { get; set; }
public int WorkerId { get; set; }
}
public class WorkerSkill
{
public int skillid { get; set; }
public string Skill { get; set; }
public int WorkerId { get; set; }
}
}
if a worker has skills from different positions the above code will not work, if this is the scenario try the below code:
var WorkerPositionSkill = from p in db.positionSkillList join q in db.workerSkillList on p.skillid equals q.skillid select new { posSkill = p, workerSkill = q };
var workerWithallSkill = (from u in db.workerList join x in db.workerSkillList on u.WorkerId equals x.WorkerId where (WorkerPositionSkill.Where(y => y.workerSkill.WorkerId == u.WorkerId && y.posSkill.PositionId == 1).Count() == db.positionSkillList.Where(p => p.PositionId == 1).Count()) select u).ToList().Distinct();
This is highly unlikely to work with Linq To SQL because...its a huge steaming pile of #$%&. But this Linq query should given a sufficiently magical IQueryProvider give the right SQL. I've seen some very magical things come from Entity Framework.
var PositionsWithSkills = from a in db.Client_Customer_Position
where a.ID == position
select new
{
PositionID = a.ID,
RequiredSkills = (from b in db.Client_Customer_Position_Skills
where b.ClientCusPosId == a.ID
select b.SkillName)
};
var WorkersWithSkills = from x in db.Workers
select new
{
workerId = x.ID,
Skills = (from y in db.Worker_Skills
where y.Worker_ID == x.ID
select y.SkillName)
};
var PositionWithSkilledWorkers = from pos in PositionsWithSkills
from worker in WorkersWithSkills
where pos.RequiredSkill.All(worker.Skills.Contains)
group worker.Name by pos.PositionID;
PS please learn to use associations as opposed to join/where. If you are going to use join/where, you might as well just use SQL.
var PositionsWithSkills = (from a in Positions select new {
PositionID = a.PositionId,
RequiredSkills = (from b in PositionSkills where b.PositionId == a.PositionId select b.skillId).ToList()
}).ToList();
var WorkersWithSkills = (from x in Workers select new {
Name = x.Name,
Skills = (from y in WorkerSkills where y.WorkerId == x.WorkerID select y.skillId).ToList()
}).ToList();
var PositionWithSkilledWorkers = (from pos in PositionsWithSkills select new {
PositionId = pos.PositionID,
Workers = (from worker in WorkersWithSkills where pos.RequiredSkills.All(skill => worker.Skills.Any(workerSkill => workerSkill == skill)) select worker.Name).ToList()
}).ToList();
i think, your database's tables have not been designed correctly...
you need a relation between worker skill and position skill, i think your tables must be desinged like this:
Skill table: SkillID, Skill
Position table: PositionID, Position
PositionSkill table: ID, SkillID, PositionID
Worker table: WorkerID, Name
WorkerSkill table: ID, SkillID, WorkerID
but by this way you designed your tables, if assume skill field (description of skills) are the same in worker skill and position skill, we can use this as a relation, and your query can be like this:
// skills of specific position
var PositionSkills = Context.PositionSkill.Where(u => u.PositionId == 1);
var WorkersWithSkills = Context.Worker
.Join(Context.WorkerSkill,
worker => worker.WorkerId,
workerSkill => workerSkill.WorkerId,
(worker, workerSkill) => new { worker, workerSkill })
.GroupBy(u => u.worker)
.Select(u => new
{
u.Key.WorkerId,
u.Key.Name,
Skills = u.Select(t => t.workerSkill.skill)
});
var SkilledWorkers = WorkersWithSkills
.Where(u => PositionSkills.All(t => u.Skills.Contains(t.skill)))
.ToList();
if you wont change your database's tables, you can add a join table between position skill and worker skill like:
WorkerPositionSkill: PositionSkillID, WorkerSkillID
Here is a LinqPad program that returns the result, { Worker = John, Position = Driver}. If I understand your requirements you want to find a worker who satisfies the conditions where the worker has all the skills required for Position = 1, which is driving and drifting skills. The query returns two rows the following [{worker = John, Position = Driver}, {worker = John, Position = Driver}]. I had to use distinct to display it once. The reason for two rows is he satisfies both driving and drifting job skills. If the position required 4 skills in which the worker met, there would be 4 duplicate rows. The unique fixes that problem. Hope this helps you along.
I created this solution in LinqPad, which is great tool with hundred's of very well documented linq query examples.
void Main()
{
// Table Setup
// ************
var position = new List<Position>();
position.Add(new Position { Id = 1, Name = "driver" });
position.Add(new Position { Id = 2, Name = "clerk" });
var positionSkill = new List<PositionSkill>();
positionSkill.Add(new PositionSkill { Id = 1, Skill = "driving", PositionId = 1 });
positionSkill.Add(new PositionSkill { Id = 2, Skill = "drifting", PositionId = 1 });
var worker = new List<Worker>();
worker.Add(new Worker { Id = 1, Name = "John" });
worker.Add(new Worker { Id = 2, Name = "alex" });
var workerSkill = new List<WorkerSkill>();
workerSkill.Add(new WorkerSkill { Id = 1, Skill = "driving", WorkerId = 1 });
workerSkill.Add(new WorkerSkill { Id = 2, Skill = "drifting", WorkerId = 1 });
// The Query
// *********
var positionValue = 1;
var r = from p in position
join ps in positionSkill on p.Id equals ps.PositionId
join ws in workerSkill on ps.Skill equals ws.Skill
join w in worker on ws.WorkerId equals w.Id
where p.Id == positionValue
select new {
PositionName = p.Name,
WorkerName = w.Name
};
// Get Distinct Names
r.Distinct().Dump();
}
// Define other methods and classes here
public class Position
{
public int Id { get; set; }
public string Name { get; set; }
}
public class PositionSkill
{
public int Id { get; set; }
public string Skill { get; set; }
public int PositionId { get; set; }
}
public class Worker
{
public int Id { get; set; }
public string Name { get; set; }
}
public class WorkerSkill
{
public int Id { get; set; }
public string Skill { get; set; }
public int WorkerId { get; set; }
}

What is the equivalent DISTINCT(sql server) in the Linq

I have a Table(Send) with columns(Id, UserId,SendDate) and another table(Receive) with columns(Id,SendId,UserName).
I want show all records in SendTable with all RecieveUserName.
for example.
(Send)
1 1 2013
2 2 2013
(Recieve)
1 1 Jack
2 1 Ema
3 2 Alex
4 2 Sara
Result
1 1 2013 Jack, Ema
2 2 2013 Alex, Sara
I use this query in SqlServer (The DISTINCT keyword eliminates duplicate rows from the results of a SELECT statement)
SELECT DISTINCT c2.Id,
(SELECT STR( UserName )+ ','
FROM dbo.Reciver c1
WHERE c1.SendId = c2.id FOR XML PATH('')) Concatenated, c2.SendDate, c2.UserId
FROM dbo.Send AS c2 INNER JOIN
dbo.Reciver ON c2.Id = dbo.Reciver.SendId
How do this query in Linq?
Distinct is also available in LINQ.
For example
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}
Product[] products = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 },
new Product { Name = "apple", Code = 10 },
new Product { Name = "lemon", Code = 9 } };
var lstDistProduct = products.Distinct();
foreach (Product p in list1)
{
Console.WriteLine(p.Code + " : " + p.Name);
}
Will return all rows.
var list1 = products.DistinctBy(x=> x.Code);
foreach (Product p in list1)
{
Console.WriteLine(p.Code + " : " + p.Name);
}
will return 9 and 4
It doesn't seem to me that you need to use Distinct in this Linq query. Assuming you have the relationships between tables set up on your linq datacontext, you can do something like this:
var result = from s in context.Send
select new {
id = s.Id,
userId = s.UserId,
date = s.SendDate,
users = s.Receive.Select(u => u.UserName)
}
Note: users will an IEnumerable<String> - you can use string.Join() on the client to join the names into a string.
Update
To return users as a string to first need to 'switch' to Linq To Objects by calling AsEnumerable() or ToList() and the Linq to Sql query.
var output = from s in result.AsEnumerable()
select new {
id = s.id,
userId = s.userId,
date = s.date,
users = string.Join(", ", s.users)
}
Also see Gert Arnolds answer for a good explanation.
What you want can only be done in two steps. Not because of the DISTINCT, but because of the FOR XML. The C# equivalent of the latter is String.Join(), but you can't use that in a linq to entities statement directly. So you must collect the required data first, then switch to linq to objects (by applying AsEnumerable) and then do the concatenation and distinct:
db.Sends
.Where(s => s.Receivers.Any())
.Select(s => new {
s.Id,
Concatenated = s.Receivers.Select(r => r.UserName)
s.SendDate,
s.UserId
})
.AsEnumerable()
.Select(x => new {
s.Id,
Concatenated = String.Join(", ", x.Concatenated)
s.SendDate,
s.UserId
})
.Distinct()

selecting a distinct combination of 2 columns in SQL

When i run a select after a number of joins on my table I have an output of 2 columns and I want to select a distinct combination of col1 and col2 for the rowset returned.
the query that i run will be smthing like this:
select a.Col1,b.Col2 from a inner join b on b.Col4=a.Col3
now the output will be somewhat like this
Col1 Col2
1 z
2 z
2 x
2 y
3 x
3 x
3 y
4 a
4 b
5 b
5 b
6 c
6 c
6 d
now I want the output should be something like follows
1 z
2 y
3 x
4 a
5 b
6 d
its ok if I pick the second column randomly as my query output is like a million rows and I really dnt think there will be a case where I will get Col1 and Col2 output to be same even if that is the case I can edit the value..
Can you please help me with the same.. I think basically the col3 needs to be a row number i guess and then i need to selct two cols bases on a random row number.. I dont know how do i transalte this to SQL
consider the case 1a 1b 1c 1d 1e 2a 2b 2c 2d 2e now group by will give me all these results where as i want 1a and 2d or 1a and 2b. any such combination.
OK let me explain what im expecting:
with rs as(
select a.Col1,b.Col2,rownumber() as rowNumber from a inner join b on b.Col4=a.Col3)
select rs.Col1,rs.Col2 from rs where rs.rowNumber=Round( Rand() *100)
now I am not sure how do i get the rownumber or the random working correctly!!
Thanks in advance.
If you simply don't care what col2 value is returned
select a.Col1,MAX(b.Col2) AS Col2
from a inner join b on b.Col4=a.Col3
GROUP BY a.Col1
If you do want a random value you could use the approach below.
;WITH T
AS (SELECT a.Col1,
b.Col2
ROW_NUMBER() OVER (PARTITION BY a.Col1 ORDER BY (SELECT NEWID())
) AS RN
FROM a
INNER JOIN b
ON b.Col4 = a.Col3)
SELECT Col1,
Col2
FROM T
WHERE RN = 1
Or alternatively use a CLR Aggregate function. This approach has the advantage that it eliminates the requirement to sort by partition, newid() an example implementation is below.
using System;
using System.Data.SqlTypes;
using System.IO;
using System.Security.Cryptography;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000)]
public struct Random : IBinarySerialize
{
private MaxSoFar _maxSoFar;
public void Init()
{
}
public void Accumulate(SqlString value)
{
int rnd = GetRandom();
if (!_maxSoFar.Initialised || (rnd > _maxSoFar.Rand))
_maxSoFar = new MaxSoFar(value, rnd) {Rand = rnd, Value = value};
}
public void Merge(Random group)
{
if (_maxSoFar.Rand > group._maxSoFar.Rand)
{
_maxSoFar = group._maxSoFar;
}
}
private static int GetRandom()
{
var buffer = new byte[4];
new RNGCryptoServiceProvider().GetBytes(buffer);
return BitConverter.ToInt32(buffer, 0);
}
public SqlString Terminate()
{
return _maxSoFar.Value;
}
#region Nested type: MaxSoFar
private struct MaxSoFar
{
private SqlString _value;
public MaxSoFar(SqlString value, int rand) : this()
{
Value = value;
Rand = rand;
Initialised = true;
}
public SqlString Value
{
get { return _value; }
set
{
_value = value;
IsNull = value.IsNull;
}
}
public int Rand { get; set; }
public bool Initialised { get; set; }
public bool IsNull { get; set; }
}
#endregion
#region IBinarySerialize Members
public void Read(BinaryReader r)
{
_maxSoFar.Rand = r.ReadInt32();
_maxSoFar.Initialised = r.ReadBoolean();
_maxSoFar.IsNull = r.ReadBoolean();
if (_maxSoFar.Initialised && !_maxSoFar.IsNull)
_maxSoFar.Value = r.ReadString();
}
public void Write(BinaryWriter w)
{
w.Write(_maxSoFar.Rand);
w.Write(_maxSoFar.Initialised);
w.Write(_maxSoFar.IsNull);
if (!_maxSoFar.IsNull)
w.Write(_maxSoFar.Value.Value);
}
#endregion
}
You need to group by a.Col1 to get distinct by only a.Col1, then since b.Col2 is not included in the group you need to find a suitable aggregate function to reduce all values in the group to just one, MIN is good enough if you just want one of the values.
select a.Col1, MIN(b.Col2) as c2
from a
inner join b on b.Col4=a.Col3
group by a.Col1
If I understand you correctly, you want to have one line for each combination in column 1 and 2. That can easily be done by using GROUP BY or DISTINCT
for instance:
SELECT col1, col2
FROM Your Join
GROUP BY col1, col2
You must use a group by clause :
select a.Col1,b.Col2
from a
inner join b on b.Col4=a.Col3
group by a.Col1