entity framework distinct by field - sql

i have table kopija that goes like this:
idKopija | idFilm | nije_tu
1 | 1 | 0
2 | 1 | 0
3 | 1 | 1
4 | 2 | 1 and etc.
And i have query that goes like this:
var upit = from f in baza.films
join z in baza.zanrs on f.idZanr equals z.idZanr
join k in baza.kopijas on f.idFilm equals k.idFilm
select new
{
idFilm = f.idFilm,
nazivFilm = f.naziv,
nazivZanr = z.naziv,
idZanr = f.idZanr,
godina = f.godina,
slika = f.slika,
klip = f.klip,
nijeTu = k.nije_tu
};
if (checkBox1.Checked)
upit = upit.Where(k => k.nijeTu == 0).Distinct();
else
{
upit = upit.Where(k => k.nijeTu == 0 || k.nijeTu == 1).Distinct();
}
Now i want to make a distinct list of "idFilm". But prolem is that I get idFilm on two places because one of them has nije_tu=0 and other one has nije_tu=1.
Please someone help me.
Thank you.

What about
upit.Where(k => k.nijeTu == 0 || k.nijeTu == 1).Select(x => x.idFilm).Distinct();
?

Related

how to fetch data of table after doing full outer join?

i am having a business problem
having a table which have following
|sku_id |solr_status |entry_context | mrp
1 active 10 20
1 inactive 10 30
1 active 10 22.5
2 inactive 10 10
2 inactive 10 31
filter the data into
table1->active
table2->inactive
now i have to do the according to condition
full outer join on 1 and 2 on sku_id.. Three possible cases
case (1 is not null, 2 is not null) => use 1
case (1 is null, 2 is not null) => use 2
case (1 is not null, 2 is null) => use 1
my code is something like that
val activeCatalog=dataframe.filter('solr_status===true).cache()
val inActiveCatalog=dataframe.filter('solr_status===false).cache()
val fullCatalog=activeCatalog.join(inActiveCatalog,Seq("sku"),joinType = "outer")
fullCatalog.show(false)
val resultCatalog = (activeCatalog,inActiveCatalog) match {
case (activeCatalog,inActiveCatalog) if(activeCatalog.count()!=0L && inActiveCatalog.count()!=0L)=>
fullCatalog.filter('solr_status===true).cache()
case (activeCatalog, inActiveCatalog) if (activeCatalog.count() == 0L && inActiveCatalog.count() != 0L) =>
fullCatalog.filter('solr_status === false).cache()
case (activeCatalog, inActiveCatalog) if (activeCatalog.count() != 0L && inActiveCatalog.count() == 0L) =>
fullCatalog.filter('solr_status === true).cache()
}
so using the approach i am getting ambiguous column error. also my
result data set should maintain the schema for active or inactive
table, doing outer join will create duplicate columns
any help ?

How to get what percentage of total users joined what number of meetings in PostgreSQL?

There are two tables, one is called "user_preference" that contains all users:
id | firstname | lastname | email |
And "match" which combines users with meetups they joined:
id | matcher | partner | meetup |
Both matcher and partner are foreign keys that represent user_preference.id, meaning that same user can be both matcher and a partner in the same meetup.
What I need to know is what percentage of total unique users joined what number of meetings.
For example:
17% of users joined 5 meetups
20% of users joined 3 meetups
40% of users joined 1 meetup
23% of users joined 0 meetups
The number of meetups should not be hardcoded but dynamic.
But I want to avoid duplication of users for a single meetup and count them only once. For example this:
id | matcher | partner | meetup |
1 | user1 | user2 | meetup1 |
2 | user1 | user3 | meetup1 |
3 | user5 | user1 | meetup1 |
4 | user6 | user1 | meetup2 |
Should count that user1 visited only 2 meetups.
What I managed to do so far is to display the count of meetups each user visited but that is not what I need:
SELECT distinct up.email users, COUNT(m.user) meetups
FROM user_preference up
LEFT JOIN
(
SELECT matcher AS user FROM match
UNION ALL
SELECT partner AS user FROM match
) m ON m.user = up.id
GROUP BY up.email
ORDER BY meetups desc;
In the end I did this by making simple queries and looping through them in the code, its far from elegant solution but it should work.
If someone posts SQL solution I will accept and upvote it...
export const getDevStats = async () => {
const users = await getRepository(UserPreference).query(
`SELECT * FROM user_preference;`
);
const meetups = await getRepository(Meetup).query(
`SELECT * FROM meetup;`
);
const matches = await getRepository(Match).query(
`SELECT * FROM match;`
);
let userMatches: any = {};
users.forEach((user: any) => {
userMatches[user.id] = []
matches.forEach((match: any) => {
if(user.id == match.matcher || user.id == match.partner) {
if(userMatches[user.id].indexOf(match.meetup) === -1) {
userMatches[user.id].push(match.meetup);
}
}
});
});
let matchStats: any = {};
for (var userId of Object.keys(userMatches)) {
if (typeof matchStats[userMatches[userId].length] === 'undefined') {
matchStats[userMatches[userId].length] = 0;
}
matchStats[userMatches[userId].length]++;
}
return {
users: users,
meetups: meetups,
matches: matches,
userMatches: userMatches,
matchStats: matchStats
};
};

How can I extract a json column into new columns automatically in Snowflake SQL?

This is as example taken from another thread, but essentially I would like to achieve this:
Sample data
ID Name Value
1 TV1 {"URL": "www.url.com", "Icon": "some_icon"}
2 TV2 {"URL": "www.url.com", "Icon": "some_icon", "Facebook": "Facebook_URL"}
3 TV3 {"URL": "www.url.com", "Icon": "some_icon", "Twitter": "Twitter_URL"}
..........
Expected output
ID Name URL Icon Facebook Twitter
1 TV1 www.url.com some_icon NULL NULL
2 TV2 www.url.com some_icon Facebook_URL NULL
3 TV3 www.url.com some_icon NULL Twitter_URL
I'm totally new to Snowflake so I'm shaking my head on how to do this easily (and hopefully automatically, in the case where some rows might have more elements in the json than other rows, which would be tedious to assign manually). Some lines might have sub-categories too.
I found the parse_json function for Snowflake, but it's only giving me the same json column in a new column, still in json format.
TIA!
You can create a view over your table with the following SELECT:
SELECT ID,
Name,
Value:URL::varchar as URL,
Value:Icon::varchar as Icon,
Value:Facebook::varchar as Facebook,
Value:Twitter::varchar as Twitter
FROM tablename;
Additional attributes will be ignored unless you add them to the view. There is no way to "automatically" include them into the view, but you could create a stored procedure that dynamically generates the view based on all the attributes that are in the full variant content of a table.
You can create a SP to automatically build the CREATE VIEW for you based on the JSON data in the VARIANT.
I have some simple example below:
-- prepare the table and data
create or replace table test (
col1 int, col2 string,
data1 variant, data2 variant
);
insert into test select 1,2, parse_json(
'{"URL": "test", "Icon": "test1", "Facebook": "http://www.facebook.com"}'
), parse_json(
'{"k1": "test", "k2": "test1", "k3": "http://www.facebook.com"}'
);
insert into test select 3,4,parse_json(
'{"URL": "test", "Icon": "test1", "Twitter": "http://www.twitter.com"}'
), parse_json(
'{"k4": "v4", "k3": "http://www.ericlin.me"}'
);
-- create the SP, we need to know which table and
-- column has the variant data
create or replace procedure create_view(
table_name varchar
)
returns string
language javascript
as
$$
var final_columns = [];
// first, find out the columns
var query = `SHOW COLUMNS IN TABLE ${TABLE_NAME}`;
var stmt = snowflake.createStatement({sqlText: query});
var result = stmt.execute();
var variant_columns = [];
while (result.next()) {
var col_name = result.getColumnValue(3);
var data_type = JSON.parse(result.getColumnValue(4));
// just use it if it is not a VARIANT type
// if it is variant type, we need to remember this column
// and then run query against it later
if (data_type["type"] != "VARIANT") {
final_columns.push(col_name);
} else {
variant_columns.push(col_name);
}
}
var columns = {};
query = `SELECT ` + variant_columns.join(', ') + ` FROM ${TABLE_NAME}`;
stmt = snowflake.createStatement({sqlText: query});
result = stmt.execute();
while (result.next()) {
for(i=1; i<=variant_columns.length; i++) {
var sub_result = result.getColumnValue(i);
if(!sub_result) {
continue;
}
var keys = Object.keys(sub_result);
for(j=0; j<keys.length; j++) {
columns[variant_columns[i-1] + ":" + keys[j]] = keys[j];
}
}
}
for(path in columns) {
final_columns.push(path + "::STRING AS " + columns[path]);
}
var create_view_sql = "CREATE OR REPLACE VIEW " +
TABLE_NAME + "_VIEW\n" +
"AS SELECT " + "\n" +
" " + final_columns.join(",\n ") + "\n" +
"FROM " + TABLE_NAME + ";";
snowflake.execute({sqlText: create_view_sql});
return create_view_sql + "\n\nVIEW created successfully.";
$$;
Execute the SP will return below string:
call create_view('TEST');
+---------------------------------------+
| CREATE_VIEW |
|---------------------------------------|
| CREATE OR REPLACE VIEW TEST_VIEW |
| AS SELECT |
| COL1, |
| COL2, |
| DATA1:Facebook::STRING AS Facebook, |
| DATA1:Icon::STRING AS Icon, |
| DATA1:URL::STRING AS URL, |
| DATA2:k1::STRING AS k1, |
| DATA2:k2::STRING AS k2, |
| DATA2:k3::STRING AS k3, |
| DATA1:Twitter::STRING AS Twitter, |
| DATA2:k4::STRING AS k4 |
| FROM TEST; |
| |
| VIEW created successfully. |
+---------------------------------------+
Then query the VIEW:
SELECT * FROM TEST_VIEW;
+------+------+-------------------------+-------+------+------+-------+-------------------------+------------------------+------+
| COL1 | COL2 | FACEBOOK | ICON | URL | K1 | K2 | K3 | TWITTER | K4 |
|------+------+-------------------------+-------+------+------+-------+-------------------------+------------------------+------|
| 1 | 2 | http://www.facebook.com | test1 | test | test | test1 | http://www.facebook.com | NULL | NULL |
| 3 | 4 | NULL | test1 | test | NULL | NULL | http://www.ericlin.me | http://www.twitter.com | v4 |
+------+------+-------------------------+-------+------+------+-------+-------------------------+------------------------+------+
Query the source table:
SELECT * FROM TEST;
+------+------+------------------------------------------+-----------------------------------+
| COL1 | COL2 | DATA1 | DATA2 |
|------+------+------------------------------------------+-----------------------------------|
| 1 | 2 | { | { |
| | | "Facebook": "http://www.facebook.com", | "k1": "test", |
| | | "Icon": "test1", | "k2": "test1", |
| | | "URL": "test" | "k3": "http://www.facebook.com" |
| | | } | } |
| 3 | 4 | { | { |
| | | "Icon": "test1", | "k3": "http://www.ericlin.me", |
| | | "Twitter": "http://www.twitter.com", | "k4": "v4" |
| | | "URL": "test" | } |
| | | } | |
+------+------+------------------------------------------+-----------------------------------+
You can refine this SP to detect nested data and have them added to the columns list as well.

Codeigniter merge into one row record with sql one to many relationship

I would like to query one to many relationship
eg:
Table A: Table B:
id | country_name id | name | table_A_id
1 | Usa 1 | kerry | 1
2 | Australia 2 | jerry | 1
3 | tommy | 2
4 | cherry | 2
my purpose is to query the result to merge one row record
eg: result list:
1 Record 2 Record
Usa Australia
kerry tommy
jeryy cherry
Currently, I am using Codeignter framework and beginner for sql, please don't mind me guys.
$this->db->select('*')
>from("table A")
->join("table B", "table.A.id = table_A_id");
$query = $this->db->get();
if($query->num_rows() > 0) {
return $query->result();
}
My view
<?php foreach($posts as $post) {
echo $post->country_name;
echo $post->name;
} ?>
However, it gives me 4 row records.
1 Record 2 Record
Usa Usa
kerry jerry
3 Record 4 Record
Australia Australia
tommy cherry
Thanks you guys in advance for helping me.
Here is what you missed
$this->db->select('*')
>from("table A")
->join("table B", "table.A.id = table_A_id");
$query = $this->db->get();
if($query->num_rows() > 0) {
return $query->result();
}
it should have been
->join("table B", 'B.table_A_id=A.id');
hope this make sense
option B
$this->db->join('table B','B.table_A_id=A.id','INNER');
$query = $this->db->get('table A');
Try out this
SELECT country, group_concat(name) FROM city c INNER JOIN employee e
ON c.id = e.city_id group by c.id
output
('USA ' , 'jerry ,kerry'),
('Australia', 'cherry ,tommy');
My solution found without using inner join:
public function mergeRecord() {
$array_store = array();
foreach($this->one() as $row) {
$child = $this->many($row['id']);
if($child) {
$return = array_merge(array("parent" => $row), array("child" =>$child));
array_push($array_store, $return);
}
}
return $array_store;
}
public function one() {
$query = $this->db->select("*")
->get("table A")
->result_array();
return $query;
}
public function many($id) {
$query = $this->db->select("id, name")
->where("table_A_id", $id)
->get("table B")
->result_array();
return $query;
}

filter data with entity framework

I'm trying to get the right data
Rooms table
Id | Name
1 Room1
2 Room2
Resources table
Id | Name
1 Resource1
2 Resource2
3 Resource3
RoomResources table
Id | RoomId | ResourceId
1 1 1
2 1 2
3 1 3
4 2 2
5 2 3
I want select a room with Resource1 and Resource2
I'm using this code
int[] ids = sResources.Split(',').Select(s => int.Parse(s)).ToArray();
rooms = from r in context.Rooms
where r.Area.Office.Id == officeId
&& r.MaximumPeople >= numberOfPeople
&& r.RoomResources.Any(s => ids.Contains(s.ResourceId))
select r;
but it return Room1 and Room2 and the result should be Room1
Maybe this?
int[] ids = sResources.Split(',').Select(s => int.Parse(s)).ToArray();
rooms = from r in context.Rooms
where r.Area.Office.Id == officeId
&& r.MaximumPeople >= numberOfPeople
&& ids.All(i => r.RoomResources.Any(s => s.ResourceId == i)) // try this here
select r;