Dataview TABLE each column has it's own condition

Hi there, i’m pretty new to obsidian.

Up till now i wasn’t able to find the solution within search. Maybe I’'m not sure what should I search for.

What I’m trying to do

I’m trying to creat a table where each column has its own condition.

I have several files structured as follows:

File 1
#tag1
country: (country_iso:: US)
type: (rad_type:: [ [[A]], [[B]], [[C]], [[D]] ])

File 2
#tag1
country: (country_iso:: FR)
type: (rad_type:: [ [[B]], [[D]] ])

File 3
#tag1
country: (country_iso:: US)
type: (rad_type:: [ [[A]], [[D]] ])

Etc…

The Table should look like this:

Things I have tried

1st step:

TABLE without ID country_iso, file.link
FROM #tag1 
WHERE contains(file.outlinks, [[A]])

It returns this:

2nd step:

TABLE file.link
FROM #tag1 
WHERE contains(file.outlinks, [[A]])
GROUP BY country_iso

returns nothing good:

and finally:

TABLE file.link WHERE contains(file.outlinks, [[A]]),
	  file.link WHERE contains(file.outlinks, [[B]]),
	  file.link WHERE contains(file.outlinks, [[C]]),
FROM #tag1 
GROUP BY country_iso

Which resulted in error:

Is there any way to create the output i’m looking for?

As far as I know you can’t include the conditions directly in the declaration (not sure if that’s the term) of the columns. You need to “outsource” those below, e.g.

TABLE ColumnA, ColumnB, ColumnC
FROM #tag1 
GROUP BY country_iso
FLATTEN choice(econtains(file.frontmatter, [[A]]) as ColumnA

That said, a) I’m not the best at this, so maybe someone else knows better, BUT b) I’m not sure dataview can actually do columns like you want. From what I see in your illustration, you’d like the columns to be essentially independent from each other, listing files that are TRUE for the condition in that column.

I’ve played around with dataview a lot, and I don’t think that’s possible
Normally, dataview will give you something like

you have the title or similar in the one field, then other fields that are related to that first one.

What you’re looking for is the filter() command, which kind of gives you the opportunity to use a WHERE in the column definitions. So try something like the following untested query:

```dataview
TABLE aLinks, bLinks, cLinks
FROM #tag1 
GROUP BY country_iso
FLATTEN list(filter(file.outlinks, (outlink) => outlink = [[A]])) as aLinks
FLATTEN list(filter(file.outlinks, (outlink) => outlink = [[B]])) as bLinks
FLATTEN list(filter(file.outlinks, (outlink) => outlink = [[C]])) as cLinks
```

This query would for each of the links, loop through all the links in file.outlinks, and only keep those matching the given link. This is done in the context of a FLATTEN list(...) as aLinks which is a construct to allow for building the new list and keeping it as a list, even though FLATTEN tends to flatten the lists by itself.

@ReaderGuy42 @holroy ,

Thank you for your replies! Combining you both solution i came up with this code:

TABLE without ID
choice(contains(file.outlinks, [[A]]), file.link, null) AS "Files linking to A", choice(contains(file.outlinks, [[B]]), file.link, null) AS "Files linking to B", choice(contains(file.outlinks, [[C]]), file.link, null) AS "Files linking to C",
choice(contains(file.outlinks, [[D]]), file.link, null) AS "Files linking to D"
WHERE contains(file.outlinks, [[A]]) OR contains(file.outlinks, [[B]]) OR contains(file.outlinks, [[C]]) OR contains(file.outlinks, [[D]])

Which gives:

However i’m not able to group by country_iso with this code:

TABLE
choice(contains(file.outlinks, [[A]]), file.link, null) AS "Files linking to A", choice(contains(file.outlinks, [[B]]), file.link, null) AS "Files linking to B", choice(contains(file.outlinks, [[C]]), file.link, null) AS "Files linking to C",
choice(contains(file.outlinks, [[D]]), file.link, null) AS "Files linking to D"
WHERE contains(file.outlinks, [[A]]) OR contains(file.outlinks, [[B]]) OR contains(file.outlinks, [[C]]) OR contains(file.outlinks, [[D]])

GROUP BY country_iso

Maybe you have some ideas what’s wrong?

What did you get when you ran my query? Did it fail? Did it solve the issue you’re still having?

Using choice() will map all the non-null entries, and not filter out those not being linked with that source.

It seems you possibly got nothing… I misread part of your request, so try this query instead:

```dataview
TABLE aLinks, bLinks, cLinks, dLinks
FROM #tag1
GROUP BY country_iso
FLATTEN list(
  map(
    filter(rows.file, 
           (file) => contains(file.outlinks, [[A]]) ), 
    (m) => m.link)) as aLinks
FLATTEN list(
  map(
    filter(rows.file, 
           (file) => contains(file.outlinks, [[B]]) ), 
    (m) => m.link)) as bLinks
FLATTEN list(
  map(
    filter(rows.file, 
           (file) => contains(file.outlinks, [[C]]) ), 
    (m) => m.link)) as cLinks
FLATTEN list(
  map(
    filter(rows.file, 
           (file) => contains(file.outlinks, [[D]]) ), 
    (m) => m.link)) as dLinks
```

You could possibly also play around a little with the FROM, as you maybe want to do something like FROM [[A]] or [[B]] or [[C]] or [[D]] to limit to only files having a link to either of the files. In my test query I also added a simple WHERE country_iso to verify that files actually had that iso defined, so they wouldn’t be lumped together in a larger anonymous group.

The query above (adopted to my test file set) gave this output:

Here is another variant building upon your suggestion using choice(), which keeps listing all null entries for a given link target:

```dataview
TABLE
  map(rows.file, (r) => choice(contains(r.outlinks, [[A]]), r.link, null)) AS "Files linking to A"
, map(rows.file, (r) => choice(contains(r.outlinks, [[B]]), r.link, null)) AS "Files linking to B"
, map(rows.file, (r) => choice(contains(r.outlinks, [[C]]), r.link, null)) AS "Files linking to C"
, map(rows.file, (r) => choice(contains(r.outlinks, [[D]]), r.link, null)) AS "Files linking to D"
FROM [[A]] or [[B]] or [[C]] or [[D]]
WHERE country_iso
GROUP BY country_iso
```

Which displays as:

Notice how a given line (seemlingly) is aligned with the file lists in the other columns. My previous query eliminated all those empty values.

Remember that whenever you do GROUP BY, all the previous data is now stored within the rows object.