How do I query array element in impala? - hadoop

I created a table in impala ,the have two columns ,
+-----------+---------------------+---------+
| name | type | comment |
+-----------+---------------------+---------+
| unique_id | string | |
| cmap | array<struct< | |
| | fieldname:string, | |
| | fieldid:string, | |
| | fielddata:string | |
| | >> | |
+-----------+---------------------+---------+
i need set the conditions for cmap to query unique_id, such as
(fieldname="ip"and fielddata="192.168.1.145") and(fieldname="wid" and fielddata="15")
i wrote this sql but can't query it, but i inserted the data in the table
sql:
select unique_id from s_click_parquet,s_click_parquet.cmap as lst where ( fieldname="ip" and fieldData="192.168.1.145") and(fieldname="wid" and fielddata="15");

You typically access arrays with square brackets, but you can have an array of structs, not just an array.
You can INLINE() an array of struct to make it multiple rows, as well as splitting the fields to queryable columns.
Then you can query it as you would a normal table.
Play around with
select *
from table1 t
lateral view inline(cmap) a;

From my work collogue:
so rule of thumb is structs can get accessed via strucName., while arrays have to be joined*
So if we have the following types from an avro schema:
case class Visit (var Patient: PatientType = null)
case class PatientType(
var Name: String = null,
var Address: List[AddressType] = null
)
case class AddressType(
var Line1: String = null,
var Line2: String = null,
var City: String = null,
var State: String = null,
var ZipCode: String = null
)
You would query for patient name and address like:
select vis.patient.name, addr.item.*
from visit vis
left join vis.patient.address addr

Related

Get original view definition from POSTGRESQL DB

I have created a view with the below definition :
CREATE TABLE t1(id int,name varchar);
INSERT INTO t1 values(1,'n1'),(2,'n2');
CREATE VIEW v2 AS SELECT * FROM t1 WHERE name = 'n1';
But when i checked the definition in postgresql DB(9.5) in pg_views table, it is getting modified in the below way :
postgres=# select * from pg_views where schemaname = 'sc1' and viewname = 'v2';
schemaname | viewname | viewowner | definition
------------+----------+-----------+-----------------------------------------
sc1 | v2 | postgres | SELECT t1.id, +
| | | t1.name +
| | | FROM sc1.t1 +
| | | WHERE ((t1.name)::text = 'n1'::text);
(1 row)
I am fine with adding tablename before columnname but i don't want the extra '::text' part.
Is there anyway to achieve this(like any other system table i can query from to get original definition)
You can not get the "original" view definition from the Postgres system tables.
Postgres only stores the parsed version.

Get records from a collection based on a list of integer ids

I have a list of integers: ids. There is also collection, IdNames which comes from an sql table. For each integer in ids I want to find the matching id in, IdNames. Then for each record in IdNames that has a matching id I'd like to select the value in the Name and DisplayName columns and the id.
So here is the table IdNames
Id | Name | DisplayName
--------------------------------
1 | fistName | firstDisplayName
2 | secondName | secondDisplayName
3 | thirdName | thirdDisplayName
If ids contained the integers 2 and 3, I'd want this collection to be returned
Id | Name | DisplayName
--------------------------------
2 | secondName | secondDisplayName
3 | thirdName | thirdDisplayName
How would I write this as a linq query?
I stared writing it like this: IdNames.Select(x => x.Id == ids.Any()), but obviously it's not right.
var idNames = from idName in DataContext.IdNames
where ids.Contains(idName.Id)
select idName;
Good enough?
Use Join in Linq-To-Objects("I have a list of integers: ids. There is also collection, IdNames"):
var query = from id in ids
join idName in IdNames
on id equals idName.Id
select idName;
Why is LINQ JOIN so much faster than linking with WHERE?

Distinct query in Criteria NHibernate

I need the corresponding query in Criteria language to this one (to retrieve all categories from my table but to distinct them):
SELECT DISTINCT categoryName
FROM Category
WHERE CategoryID IN (
SELECT CategoryID
FROM FoodCategory
)
ORDER BY categoryName
I have table FoodCategory table
id | FoodID | CategoryID
--------|---------------|------------
| |
| |
| |
Actually CategoryID is a foreign key that is pointing to this table here. This is table for Category:
CategoryID | categoryName | otherField
---------------|------------------|------------
| |
| |
| |
And this is table for Food:
FoodID | FoodName | otherField
---------------|------------------|------------
| |
| |
| |
Something like that should do the trick :
public List<String> retrieveFoodCategoryNames() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<String> criteriaQuery = builder.createQuery(String.class);
Root<FoodCategory> root = criteriaQuery.from(FoodCategory.class);
// by default an inner join so it will only get the categories which have their id in the FoodCategory table
Join<FoodCategory, Category> joinCategory = root.join(FoodCategory_.category);
Fetch<FoodCategory, Category> fetchCategory = root.fetch(FoodCategory_.category);
Path<String> categoryNamePath = fetchCategory.get(Category_.categoryName);
criteriaQuery.select(categoryNamePath).distinct(true);
criteriaQuery.orderBy(builder.asc(categoryNamePath));
return entityManager.createQuery(criteriaQuery).getResultList();
}
This is not the exact same SQL request because you used a subquery where I'm using a join but it seemed more suited to this particular case. The subquery syntax is a bit more complex and I will not try to write it without compiling! ^^
If something is unclear let me know :-)

How to write a left join with many to many relationship

I have the following entities:
Entity: Department
DepartmentId (int)
Name (int)
SuperiorDepartmentId (int, foreign key to department entity)
DepartmentPermissions (ICollection)
Entity: DepartmentPermission
DepartmentId (int)
UserId (int)
Permission (String)
Departments (ICollection)
Entity: User
UserId (int)
Name (string)
DepartmentPermissions (ICollection)
I need to return in my query all of the departments (including the ones where the user don't have permission) and the name of the permission when the user has any.
Department
DepartmentId | Name | SuperiorDepartmentId
1 | Sales | null
2 | Internal Sales | 1
3 | Marketing | null
DepartmentPermissions
DepartmentId | User Id | Permission
1 | 2 | r
2 | 2 | rw
1 | 3 | rw
User
UserId | Name
1 | John
2 | Mary
3 | Paul
If I ask for the data for user Mary (id=2), we shoud have as result set:
DepartmentId | Name | SuperiorDepartmentId | Permission
1 | Sales | null | r
2 | Internal Sales | 1 | rw
3 | Marketing | null | null
How can I do this?
I'm going to presume the existence of a navigation property Department.DepartmentPermissions.
var query = from d in context.Departments
select new {
Department = d,
Permissions = d.DepartmentPermissions
.Where(dp => dp.UserId == 2)
.Select(p => p.Permission)
};
var result = query.AsEnumerable()
.Select(x =>
new {
x.Department.DepartmentId,
x.Department.Name,
x.Department.SuperiorDepartmentId,
Permissions =
string.Join(", ", x.Permissions.DefaultIfEmpty("null")
}
First the raw data are collected (query), then the final results are composed in memory. The latter is done because EF won't allow string.Join in a LINQ query. Your data structure allows for more than one permission per user in one department, hence the string.Join.
If you're absolutely sure that there will always be one permission you can do
Permission = d.DepartmentPermissions.Where(dp => dp.UserId == 2)
.Select(p => p.Permission)
.FirstOrDefault()
in query, and your done.

Select nested list

I have three tables in DB like this:
products
+----+------+
| id | name |
+----+------+
| 1 | prod1|
+----+------+
values
+----+---------+---------+
| id | value | alias |
+----+---------+---------+
| 1 | 10 g | 10m |
+----+---------+---------+
prdoucts_values
+---------------+---------+
| product_id | value_id|
+---------------+---------+
| 1 | 1 |
+---------------+---------+
How select all products from DB, that have any value from List<Values.alias> ?
List<decimal> aliases = ...
var query = db.Products.Where(p => p.Values.Any(v => aliases.Contains(v.Alias)));
Or (if you don't have navigation properties)
var query = from p in db.Products
join pv in db.ProductsValues on p.ProductId equals v.ProductId
join v in db.Values on pv.ValueId equals v.ValueId into values
where values.Any(v => aliases.Contains(v.Alias))
select p
If you are using EF (database first) then the table prdoucts_values is not part of the conseptual model.
instead EF givs you a direct path from Products to Values
Therefore you can write a query that look like this:
var lst = new List<Products>();
lst = db.Products.Where(c => c.Values.Any()).ToList();

Resources