Concat все значения столбцов в sql

Версия с VerticalContentAlignment (для вертикальных панелей):

public class AlignableWrapPanel : Panel {
    public AlignableWrapPanel() {
        _orientation = Orientation.Horizontal;
    }

    private static bool IsWidthHeightValid(object value) {
        var v = (double)value;
        return (double.IsNaN(v)) || (v >= 0.0d && !double.IsPositiveInfinity(v));
    }

    public static readonly DependencyProperty ItemWidthProperty = DependencyProperty.Register("ItemWidth", typeof(double),
            typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure),
            IsWidthHeightValid);

    [TypeConverter(typeof(LengthConverter))]
    public double ItemWidth {
        get { return (double)GetValue(ItemWidthProperty); }
        set { SetValue(ItemWidthProperty, value); }
    }

    public static readonly DependencyProperty ItemHeightProperty = DependencyProperty.Register("ItemHeight", typeof(double),
            typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure),
            IsWidthHeightValid);

    [TypeConverter(typeof(LengthConverter))]
    public double ItemHeight {
        get { return (double)GetValue(ItemHeightProperty); }
        set { SetValue(ItemHeightProperty, value); }
    }

    public static readonly DependencyProperty OrientationProperty = StackPanel.OrientationProperty.AddOwner(typeof(AlignableWrapPanel),
            new FrameworkPropertyMetadata(Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure, OnOrientationChanged));

    public Orientation Orientation {
        get { return _orientation; }
        set { SetValue(OrientationProperty, value); }
    }

    private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        var p = (AlignableWrapPanel)d;
        p._orientation = (Orientation)e.NewValue;
    }

    private Orientation _orientation;

    private struct UvSize {
        internal UvSize(Orientation orientation, double width, double height) {
            U = V = 0d;
            _orientation = orientation;
            Width = width;
            Height = height;
        }

        internal UvSize(Orientation orientation) {
            U = V = 0d;
            _orientation = orientation;
        }

        internal double U;
        internal double V;
        private readonly Orientation _orientation;

        internal double Width {
            get { return (_orientation == Orientation.Horizontal ? U : V); }
            private set { if (_orientation == Orientation.Horizontal) U = value; else V = value; }
        }

        internal double Height {
            get { return (_orientation == Orientation.Horizontal ? V : U); }
            private set { if (_orientation == Orientation.Horizontal) V = value; else U = value; }
        }
    }

    protected override Size MeasureOverride(Size constraint) {
        var curLineSize = new UvSize(Orientation);
        var panelSize = new UvSize(Orientation);
        var uvConstraint = new UvSize(Orientation, constraint.Width, constraint.Height);
        var itemWidth = ItemWidth;
        var itemHeight = ItemHeight;
        var itemWidthSet = !double.IsNaN(itemWidth);
        var itemHeightSet = !double.IsNaN(itemHeight);

        var childConstraint = new Size(
                (itemWidthSet ? itemWidth : constraint.Width),
                (itemHeightSet ? itemHeight : constraint.Height));

        var children = InternalChildren;

        for (int i = 0, count = children.Count; i < count; i++) {
            var child = children[i];
            if (child == null) continue;

            //Flow passes its own constrint to children 
            child.Measure(childConstraint);

            //this is the size of the child in UV space 
            var sz = new UvSize(
                    Orientation,
                    (itemWidthSet ? itemWidth : child.DesiredSize.Width),
                    (itemHeightSet ? itemHeight : child.DesiredSize.Height));

            if (curLineSize.U + sz.U > uvConstraint.U) {
                //need to switch to another line 
                panelSize.U = Math.Max(curLineSize.U, panelSize.U);
                panelSize.V += curLineSize.V;
                curLineSize = sz;

                if (!(sz.U > uvConstraint.U)) continue;
                //the element is wider then the constrint - give it a separate line
                panelSize.U = Math.Max(sz.U, panelSize.U);
                panelSize.V += sz.V;
                curLineSize = new UvSize(Orientation);
            } else {
                //continue to accumulate a line
                curLineSize.U += sz.U;
                curLineSize.V = Math.Max(sz.V, curLineSize.V);
            }
        }

        //the last line size, if any should be added 
        panelSize.U = Math.Max(curLineSize.U, panelSize.U);
        panelSize.V += curLineSize.V;

        //go from UV space to W/H space
        return new Size(panelSize.Width, panelSize.Height);
    }

    protected override Size ArrangeOverride(Size finalSize) {
        var firstInLine = 0;
        var itemWidth = ItemWidth;
        var itemHeight = ItemHeight;
        double accumulatedV = 0;
        var itemU = (Orientation == Orientation.Horizontal ? itemWidth : itemHeight);
        var curLineSize = new UvSize(Orientation);
        var uvFinalSize = new UvSize(Orientation, finalSize.Width, finalSize.Height);
        var itemWidthSet = !double.IsNaN(itemWidth);
        var itemHeightSet = !double.IsNaN(itemHeight);
        var useItemU = (Orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet);

        var children = InternalChildren;

        for (int i = 0, count = children.Count; i < count; i++) {
            var child = children[i];
            if (child == null) continue;

            var sz = new UvSize(
                    Orientation,
                    (itemWidthSet ? itemWidth : child.DesiredSize.Width),
                    (itemHeightSet ? itemHeight : child.DesiredSize.Height));

            if (curLineSize.U + sz.U > uvFinalSize.U) {
                //need to switch to another line 
                ArrangeLine(finalSize, accumulatedV, curLineSize, firstInLine, i, useItemU, itemU);

                accumulatedV += curLineSize.V;
                curLineSize = sz;

                if (sz.U > uvFinalSize.U) {
                    //the element is wider then the constraint - give it a separate line 
                    //switch to next line which only contain one element 
                    ArrangeLine(finalSize, accumulatedV, sz, i, ++i, useItemU, itemU);

                    accumulatedV += sz.V;
                    curLineSize = new UvSize(Orientation);
                }

                firstInLine = i;
            } else {
                //continue to accumulate a line
                curLineSize.U += sz.U;
                curLineSize.V = Math.Max(sz.V, curLineSize.V);
            }
        }

        //arrange the last line, if any
        if (firstInLine < children.Count) {
            ArrangeLine(finalSize, accumulatedV, curLineSize, firstInLine, children.Count, useItemU, itemU);
        }

        return finalSize;
    }

    private void ArrangeLine(Size finalSize, double v, UvSize line, int start, int end, bool useItemU, double itemU) {
        double u;
        var isHorizontal = Orientation == Orientation.Horizontal;

        if (_orientation == Orientation.Vertical) {
            switch (VerticalContentAlignment) {
                case VerticalAlignment.Center:
                    u = (finalSize.Height - line.U) / 2;
                    break;
                case VerticalAlignment.Bottom:
                    u = finalSize.Height - line.U;
                    break;
                default:
                    u = 0;
                    break;
            }
        } else {
            switch (HorizontalContentAlignment) {
                case HorizontalAlignment.Center:
                    u = (finalSize.Width - line.U) / 2;
                    break;
                case HorizontalAlignment.Right:
                    u = finalSize.Width - line.U;
                    break;
                default:
                    u = 0;
                    break;
            }
        }

        var children = InternalChildren;
        for (var i = start; i < end; i++) {
            var child = children[i];
            if (child == null) continue;
            var childSize = new UvSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height);
            var layoutSlotU = (useItemU ? itemU : childSize.U);
            child.Arrange(new Rect(
                    isHorizontal ? u : v,
                    isHorizontal ? v : u,
                    isHorizontal ? layoutSlotU : line.V,
                    isHorizontal ? line.V : layoutSlotU));
            u += layoutSlotU;
        }
    }

    public static readonly DependencyProperty HorizontalContentAlignmentProperty = DependencyProperty.Register(nameof(HorizontalContentAlignment), typeof(HorizontalAlignment),
            typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(HorizontalAlignment.Left, FrameworkPropertyMetadataOptions.AffectsArrange));

    public HorizontalAlignment HorizontalContentAlignment {
        get { return (HorizontalAlignment)GetValue(HorizontalContentAlignmentProperty); }
        set { SetValue(HorizontalContentAlignmentProperty, value); }
    }

    public static readonly DependencyProperty VerticalContentAlignmentProperty = DependencyProperty.Register(nameof(VerticalContentAlignment), typeof(VerticalAlignment),
            typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(VerticalAlignment.Top, FrameworkPropertyMetadataOptions.AffectsArrange));

    public VerticalAlignment VerticalContentAlignment {
        get { return (VerticalAlignment)GetValue(VerticalContentAlignmentProperty); }
        set { SetValue(VerticalContentAlignmentProperty, value); }
    }
}
27
задан Quassnoi 9 June 2009 в 14:56
поделиться

9 ответов

Предполагая, что это один столбец с несколькими значениями, этот подход работает для MS SQL Server (я не могу говорить о других системах).

declare @result varchar(max)
set @result = ''

select @result = @result + RES
from (query goes here)
3
ответ дан 28 November 2019 в 04:40
поделиться

В SQL Server :

SELECT  col1 AS [text()]
FROM    foo
FOR XML PATH ('')

В MySQL :

SELECT  GROUP_CONCAT(col1 SEPARATOR '')
FROM    foo

В PostgreSQL :

SELECT  array_to_string
        (
        ARRAY
        (
        SELECT  col1
        FROM    foo
        ), ''
        )

В ] Oracle :

SELECT  *
FROM    (
        SELECT  col1, ROW_NUMBER() OVER(ORDER BY 1) AS rn
        FROM    foo
        MODEL
        DIMENSION BY
                (rn)
        MEASURES
                (col1, col1 AS group_concat, 0 AS mark)
        RULES UPDATE (
                group_concat[rn > 1] =  group_concat[CV() - 1] || col1[CV()],
                mark[ANY] = PRESENTV(mark[CV() + 1], 0, 1)
                )
        )
WHERE   mark = 1
49
ответ дан 28 November 2019 в 04:40
поделиться

Путь mysql:

select group_concat(somecolumn separator '') from sometable
4
ответ дан 28 November 2019 в 04:40
поделиться
select cast(res1 as varchar)+cast(res2 as varchar)+cast(res3 as varchar) as fooconcat from foo

Если столбцы уже являются строками, преобразование не требуется, вы можете просто сделать:

select res1 + res2 + res3  as fooconcat from foo

Для данных из нескольких строк используйте PIVOT .

0
ответ дан 28 November 2019 в 04:40
поделиться

Объединение строк зависит от используемой базы данных (вы не упомянули, какая версия в вашем вопросе, так что здесь) ...

В Oracle и DB2 вы можете использовать CONCAT функция ... CONCAT (строка, строка)

SQL Server вы можете использовать оператор '+' ... строка1 + строка2 + строка3

В MySQL это CONCAT (string, string ... n_string)

Наконец, в PostgreSQL это TEXTCAT (string, string) ...

... Я взял это из этой маленькой классной книжки, которая у меня есть сижу на моем столе Карманное руководство по SQL от O'Reilly ... проверьте это!

:)

0
ответ дан 28 November 2019 в 04:40
поделиться

Возможно, это не то, что вы ищете, но в прошлом мне везло с такими конструкциями:

SELECT      MAX(DECODE(fookey, 1, foo, NULL))
         || MAX(DECODE(fookey, 2, foo, NULL))
         || MAX(DECODE(fookey, 3, foo, NULL))
         || MAX(DECODE(fookey, 4, foo, NULL))
       , groupingvalue
    FROM mytable
GROUP BY groupingvalue;

Он не зависит от платформы и хорошо работает, когда у вас есть произвольное, но ограниченное количество значений для foo, и они основаны на некотором другом значении ключа. Например, если у вас есть таблица счетов-фактур, и вы хотите видеть все строки из счета-фактуры в одной строке, объединенной, и у вас есть верхний предел в 5 строк, это будет выглядеть следующим образом:

SELECT      MAX(DECODE(lineno, 1, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 2, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 3, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 4, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 5, foo, NULL))
       , invoiceid
    FROM lineitem
GROUP BY invoiceid;
0
ответ дан 28 November 2019 в 04:40
поделиться

Вот ответ, который вы ищете; У меня было ощущение, что решение лежит в операции CONNECT BY, я просто раньше не использовал псевдоколонку SYS_CONNECT_BY_PATH (которая отображает полный путь к узлу в дереве, разделяя имена узлов знаком «/»). Предполагая, что ваш набор значений «foo» до этого представляет собой несколько строк в таблице, сгруппированных по столбцу «myKey», например:

myKey    foo
-------- ----------
group 1  apple
group 1  orange
group 1  pear
group 2  ape
group 2  bear
group 2  kitten

, вы можете обрабатывать данные, как если бы это была древовидная схема, и притвориться, что значения каждого группа представляет узлы, идущие вниз по ветке. В этом случае вы должны сделать следующее:

  SELECT myKey
       , SUBSTR(MAX(REPLACE(SYS_CONNECT_BY_PATH(foo, '/')
                           ,'/'
                           ,' '
                           )
                   )
               ,2
               ) FooConcat
    FROM ( SELECT MyKey
                , Foo
                , row_number() OVER (Partition by myKey order by myKey) NodeDepth
             FROM MyTable
         )
   START WITH NodeDepth = 1
 CONNECT BY PRIOR myKey = myKey
     AND PRIOR NodeDepth = NodeDepth -1
GROUP BY myKey
;

Конечно, порядок конкатенированных значений будет случайным; если в вашей таблице был другой столбец («полоса»), который можно было использовать в качестве поля для упорядочивания, которое было восходящим и непрерывным,

1
ответ дан 28 November 2019 в 04:40
поделиться

Решение Oracle Quassnoi впечатляет, но я нашел более простые решения, используя SYS_CONNECT_BY_PATH (), а не магию MODEL.

SELECT REPLACE(MAX(SYS_CONNECT_BY_PATH(foo, '/')), '/', '') conc
FROM (
    SELECT T_FOO.*, ROW_NUMBER() OVER (ORDER BY FOO) R FROM T_FOO
)
START WITH r=1
CONNECT BY PRIOR r = r-1;
9
ответ дан 28 November 2019 в 04:40
поделиться

Выберите ([col1] + ',' + [col2] + ',' + [col3] + ',' + [col4]) как [MyCol] из [Table]

-2
ответ дан 28 November 2019 в 04:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: