L
L
lolrofl012021-05-04 21:53:33
Laravel
lolrofl01, 2021-05-04 21:53:33

How to specify table name in result using union?

I implement search in several tables in a DB. Now this is the option:

$pages = Page::select('pages.id', 'pages.title', 'pages.slug')->where('title', 'LIKE', '%' . $string . '%');
$categories = Category::select('categories.id', 'categories.name', 'categories.fullSlug')->where('name', 'LIKE', '%' . $string . '%');
//Еще несколько таких же конструкций
$results = DB::table('posts as post')->select('post.id', 'post.title', 'post.slug')->where('title', 'LIKE', '%' . $string . '%')
$results = $results->union($pages)->union($categories)->get();

Output for the query "kat":
#items: array:16 [
    0 => {#1279
        +"id": 126
        +"title": "Категория 2"
        +"slug": "category-2"
    }
    1 => {#1281
        +"id": 745
        +"title": "Пост в категории"
        +"slug": "post-in-category"
    }
    2 => {#1424
        +"id": 801
        +"title": "Страница-кат"
        +"slug": "page-cat"
    }
...
]


And here's the rub. All 3 results from 3 different tables. Moreover, the very first category, it does not have a title value, instead it has a name. But her name is still displayed as title. How to find out from which table the value was found? Because I need to divide requests into categories.

They say it is necessary to write "From table as table1" like that, I tried - aliases do not play any role, the conclusion is similar. There is another option, to set aliases in the select. Type: 'category.name as category_name' and the like. But what if we are looking up 10 tables? What if it's 20? It’s hard to give everyone aliases, and, most importantly, then write conditions like this on the view:
if( isset($result->category_name) ) {
//this is categories table
}


How to push the table name into the output (result) so that the output becomes like this?:
#items: array:16 [
0 => {#1279
    +"id": 126
    +"title": "Категория 2"
    +"slug": "category-2",
    'table' : 'categories'
}
1 => {#1281
    +"id": 745
    +"title": "Пост в категории"
    +"slug": "post-in-category",
    'table' : 'posts'
    }
    2 => {#1424
    +"id": 801
    +"title": "Страница-кат"
    +"slug": "page-cat",
    'table' : 'pages'
    }
...
]

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Ukolov, 2021-05-04
@lolrofl01

Union implies that all samples have the same structure and columns, so it takes the names from the first sample.
You can add like this:

select('pages.id', 'pages.title', 'pages.slug', DB::raw('"page" as `type`'))

The syntax in details may be different, I can’t check how exactly it should be now, but the meaning is this - just select the line in a separate column.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question